【发布时间】:2021-03-12 11:05:07
【问题描述】:
我需要将一个文件二进制文件复制到另一个 C 中。所有文件都是 UTF-16。
我会从用户那里收到源(要读取的)文件是 unix、mac 还是 windows。
另外,我将从用户那里收到目标文件(要写入)是 unix、mac 还是 windows。
复制每个字节时应该注意什么?
我有一个缓冲区unsigned char buffer[2];,我像这样复制每个字节:
while (fread(buffer,sizeof(buffer),1,source) != 0) {
fwrite(buffer,sizeof(buffer),1,target);
}
现在我只关注“线路断路器”。例如(从 unix 到 mac),我这样做:
if (buffer[0] == 0x000a) {
buffer[0] = 0x000d;
}
if (buffer[1] == 0x000a) {
buffer[1] = 0x000d;
}
试图从\n 更改为\r。
** 我可以假设每个文件的开头都会有一个 BOM。
在进行此转换时,我还有什么需要注意的吗?我应该在第一个 BOM 字符中更改某些内容吗?我应该使用该程序根据计算机的字节序检查字节顺序吗?还有其他可能出错的地方吗?
谢谢
【问题讨论】:
-
所以您正在逐字节处理未知字节序的 UTF-16 并处理您遇到的所有 0d 或 0a 字节?你知道这些字节也会出现在其他 unicode 字符中,对吧?
-
UTF-16 编码文件有(至少)三种类型:带有 BOM 的 UTF-16 和可能的字节序,UTF-16LE 总是小端,没有 BOM,以及 UTF-16BE 总是大端没有 BOM。如果使用后两者,您需要通过某种方式知道正在使用哪一个,因为您无法检查 BOM。被告知平台表明您可能需要进行行尾转换,因此您必须知道哪个在起作用。
-
您可能应该解析 BOM 并根据它在大和小之间调整您的处理。即使您只想处理换行符。
-
您可能会通过检查 0a/0d + 另一个字节为零而侥幸逃脱。 0a00 什么都不是,0d00 是马拉雅拉姆语,如果你不使用它,那应该是安全的。
-
我可以假设 BOM 将出现在每个文件中。然后我应该根据程序运行的计算机更改目标文件中的 BOM 吗?我是否也应该根据字节序检查 0x000a 或 0xa000 吗?根据字节序进行复制时是否应该反转每个位?
标签: c file binary operating-system low-level