打印机SPL文件提取
为了方便管理打印机文件,提取打印机EMF文件,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;
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 == 12 && buffer == 0 && buffer == 0 && buffer == 0 && buffer == 1 && buffer == 0 && buffer == 0 && buffer == 0)
{
//记录emf起始位置
_startIndexs.Add(whileCount *( 20 * 1024 * 1024) + j + 8);
//记录emf大小
_emfDataCount.Add((buffer) * 256 * 256 * 256 + (buffer) * 256 * 256 + (buffer) * 256 + (buffer));
}
}
}
else
{
//当“0C 00 00 00”在数组倒数第二个单位时,需要判断循环读取第二遍时数组第一个单位是否是“01 00 00 00”
if (j == 20 * 1024 * 1024-8)
{
if (buffer == 12 && buffer == 0 && buffer == 0 && buffer == 0)
{
//记录emf起始位置
_startIndexs.Add(whileCount * (20 * 1024 * 1024) + j + 8);
//记录emf大小
_emfDataCount.Add((buffer) * 256 * 256 * 256 + (buffer) * 256 * 256 + (buffer) * 256 + (buffer));
flag = true;
flagB = true;
}
}
//当“0C 00 00 00”在数组倒数第一个单位时,需要判断循环读取第二遍时数组第二个单位是否是“01 00 00 00”
if (j == 20 * 1024 * 1024-4)
{
if (buffer == 12 && buffer == 0 && buffer == 0 && buffer == 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 == 1 && buffer == 0 && buffer == 0 && buffer == 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 == 1 && buffer == 0 && buffer == 0 && buffer == 0))
{
_startIndexs.RemoveAt(_startIndexs.Count - 1);
}
else
{
_emfDataCount.Add((buffer) * 256 * 256 * 256 + (buffer) * 256 * 256 + (buffer) * 256 + (buffer));
}
}
}
}
//如果SPL文件没读完,则继续读第二遍,直到读完
i = fsR.Read(buffer, 0, buffer.Length);
}
}
}
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;
//将读取到的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;
int emfDataCount = _emfDataCount;
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;
}
}
}
}
}
} 非专业人员,完全没看懂。 学习一下,认真了解中。 这个怎么用啊,可以提取标签打印机的模板吗 nodmail 发表于 2023-7-15 11:29
非专业人员,完全没看懂。
啊啊啊~~没看懂+1 虽然我没看懂 但是还是要表扬你
看不懂,但还是要竖起拇指表扬下 学习了,谢谢版主!!! 表示没看懂学习 在学习中进步成长
页:
[1]