在我从该网站获得的Desiginin File Formats链接中,我注意到png具有CRLF\x1A\LF
块,用于“测试”回车和换行。
我正在为某个项目构建自定义的二进制结构,我想知道为什么这样做有用,在哪种情况下我应该考虑添加它?
答案 0 :(得分:3)
从历史上讲,不同的操作系统使用不同的序列来标记文本文件中的行尾:
\n
(换行符)\r\n
(回车,换行)\r
(回车)(Mac OS X(具有BSD Unix内核)可能同时支持A Line Break Is a Line Break)。这真是一团糟,例如:
^M
装饰。一旦您在不同的操作系统之间进行定期切换,就会开始习惯必须不时地确定行尾。为此有许多辅助工具。 cygwin中的unix2dos
和dos2unix
,Notepad ++中的特殊命令,VisualStudio中的提示等。
在C语言中,即使在DOS和Windows中,行尾也始终用\n
标记。 (我没有使用Mac OS的经验,但我想知道那里是否不一样。)为了使这项工作看起来很顺利,MS决定在“在幕后”读写时“修复”文件内容。在读取文件时,所有出现的\r\n
被\n
静默替换,而文件写入在每次写入的\r
之前插入一个\n
。
这有一些烦人的缺点:
如果读取某个大小的文件,则“已接收”的内容可能会小一些字节。 (当我试图在文件加载之前保留空间并一次读取全部内容时,我曾偶然发现这一点。我想知道为什么加载后似乎有些字节丢失了。)
这可能会中断二进制文件的加载,其中\n
仅表示具有任何含义的二进制值10(在换行符之外)。
为解决此问题,C API提供了文件I / O的其他模式。例如。 fopen()
支持r
,w
和a
以外的其他字符,用于指示文件类型
b
表示二进制I / O(请勿触摸内容)t
表示文本I / O(固定行尾)。没有任何一个,默认值为文本I / O。
在Windows以及可移植文件I / O上,应始终给出该值。 (在Linux上,它根本没有任何作用,尤其是没有损坏。)
我曾经写过一个对SO: Copying a bmp in c的答案,其中转储了一个损坏的BMP文件,很好地说明了错误的完成文件输出的影响。
关于文本和二进制文件I / O的漫长故事之后,很明显,对于处理图像数据(通常是二进制编码的图像数据)的开发人员来说,这始终是一个潜在的问题。
因此,我可以想象\r\n\032\n
序列仅仅是为此的测试模式。如果这4个字节不完全具有这些值,则很有可能
在这种情况下,解码器将抛出有用的错误消息,而不是神秘地失败。