为了方便管理打印机文件,提取打印机EMF文件,C#:
核心函数代码如下:
[C#] 纯文本查看 复制代码 class Program
{
//用一个列表记录一个SPL文件中所有EMF文件的起始位置
private static List<int> _startIndexs;
//用一个列表记录一个SPL文件中所有EMF文件的数据大小
private static List<int> _emfDataCount;
private static void FindEmf(string srcFilePath)
{
//初始化两个用来记录EMF文件开始位置和大小的列表
_startIndexs = new List<int>();
_emfDataCount = new List<int>();
//读取SPL文件
using (FileStream fsR = new FileStream(srcFilePath, FileMode.Open, FileAccess.Read))
{
//设置一个20M的字节数组作为缓存区来记录读取的数据
byte[] buffer = new byte[20 * 1024 * 1024];
int i = fsR.Read(buffer, 0, buffer.Length);
//当SPL文件超过20M时,需要读取多遍来记录数据,whileCount用来记录读取的遍数
int whileCount = -1;
bool flag = false;
bool flagB = false;
//当i=0时,说明已经读取完SPL文件
while (i > 0)
{
whileCount++;
//遍历缓存区数组
for (int j = 0; j < i; j++)
{
if (!flag)
{
if (j <= 20 * 1024 * 1024-12)
{
if (j % 4 == 0)
{
//找到“0C 00 00 00 XX XX XX XX 01 00 00 00”
if (buffer[j] == 12 && buffer[j + 1] == 0 && buffer[j + 2] == 0 && buffer[j + 3] == 0 && buffer[j + 8] == 1 && buffer[j + 9] == 0 && buffer[j + 10] == 0 && buffer[j + 11] == 0)
{
//记录emf起始位置
_startIndexs.Add(whileCount *( 20 * 1024 * 1024) + j + 8);
//记录emf大小
_emfDataCount.Add((buffer[j + 7]) * 256 * 256 * 256 + (buffer[j + 6]) * 256 * 256 + (buffer[j + 5]) * 256 + (buffer[j + 4]));
}
}
}
else
{
//当“0C 00 00 00”在数组倒数第二个单位时,需要判断循环读取第二遍时数组第一个单位是否是“01 00 00 00”
if (j == 20 * 1024 * 1024-8)
{
if (buffer[j] == 12 && buffer[j + 1] == 0 && buffer[j + 2] == 0 && buffer[j + 3] == 0)
{
//记录emf起始位置
_startIndexs.Add(whileCount * (20 * 1024 * 1024) + j + 8);
//记录emf大小
_emfDataCount.Add((buffer[j + 7]) * 256 * 256 * 256 + (buffer[j + 6]) * 256 * 256 + (buffer[j + 5]) * 256 + (buffer[j + 4]));
flag = true;
flagB = true;
}
}
//当“0C 00 00 00”在数组倒数第一个单位时,需要判断循环读取第二遍时数组第二个单位是否是“01 00 00 00”
if (j == 20 * 1024 * 1024-4)
{
if (buffer[j] == 12 && buffer[j + 1] == 0 && buffer[j + 2] == 0 && buffer[j + 3] == 0)
{
//记录emf起始位置
_startIndexs.Add(whileCount * (20 * 1024 * 1024) + j + 8);
flag = true;
}
}
}
}
//在上一次循环中,“0C 00 00 00”在数组倒数第二个单位或者倒数第一个单位时
//需要判断此次循环读取数组第一个单位或者第二个单位是否是“01 00 00 00”
else
{
flag = false;
if (_startIndexs.Count == _emfDataCount.Count)
{
if (!(buffer[j] == 1 && buffer[j + 1] == 0 && buffer[j + 2] == 0 && buffer[j + 3] == 0))
{
_startIndexs.RemoveAt(_startIndexs.Count - 1);
_emfDataCount.RemoveAt(_emfDataCount.Count - 1);
}
}
else
{
if (flagB)
{
flagB = false;
_startIndexs.RemoveAt(_startIndexs.Count - 2);
_emfDataCount.RemoveAt(_emfDataCount.Count - 1);
}
if (!(buffer[j + 4] == 1 && buffer[j + 5] == 0 && buffer[j + 6] == 0 && buffer[j + 7] == 0))
{
_startIndexs.RemoveAt(_startIndexs.Count - 1);
}
else
{
_emfDataCount.Add((buffer[j + 3]) * 256 * 256 * 256 + (buffer[j + 2]) * 256 * 256 + (buffer[j + 1]) * 256 + (buffer[j]));
}
}
}
}
//如果SPL文件没读完,则继续读第二遍,直到读完
i = fsR.Read(buffer, 0, buffer.Length);
}
}
}
[C#] 纯文本查看 复制代码 public static void SplToEmf(string srcFilePath, string dstFilePath)
{
//找到当前SPL文件中所有EMF文件的开始位置和数据大小
FindEmf(srcFilePath);
//遍历记录EMF文件开始位置的列表,从而读取所有EMF文件
for (int j = 0; j < _startIndexs.Count; j++)
{
//读取SPL文件
using (FileStream fsR = new FileStream(srcFilePath, FileMode.Open, FileAccess.Read))
{
//用20M的字节数组作为缓存区读取SPL文件
byte[] buffer = new byte[20 * 1024 * 1024];
//将读取到的EMF文件数据记录下来
using (FileStream fsW = new FileStream(Path.Combine(dstFilePath, Path.GetFileNameWithoutExtension(srcFilePath) + "-" + j.ToString() + ".emf"), FileMode.Create, FileAccess.Write))
{
int i = fsR.Read(buffer, 0, buffer.Length);
int startIndex = _startIndexs[j];
int emfDataCount = _emfDataCount[j];
int X = startIndex;
//remnant记录剩余没读完的EMF数据
int remnant = emfDataCount;
//remnant剩余数据为0时读完一个EMF文件数据
while (remnant > 0)
{
//当EMF文件的起始位置在20M的缓存区内时,开始读取
//否则循环读取SPL文件,在下一个缓存中开始找开始位置
if (startIndex <= 20 * 1024 * 1024 - 1)
{
if (remnant > i - X)
fsW.Write(buffer, X, i - X);
else
fsW.Write(buffer, X, remnant);
remnant = remnant - (i - X);
i = fsR.Read(buffer, 0, buffer.Length);
X = 0;
}
else
{
i = fsR.Read(buffer, 0, buffer.Length);
startIndex = startIndex - 20 * 1024 * 1024;
X = 0;
}
}
}
}
}
} |