chu*_*ica 12 c binary file-io fseek
C规范有一个有趣的脚注(#268C11dr§7.21.39)
"将文件位置指示器设置为文件结尾,如同
fseek(file, 0, SEEK_END)
,具有二进制流的未定义行为(因为可能存在尾随空字符)或具有状态相关编码但未确定以初始移位状态结束的任何流".
这是否适用于读取文件的二进制流?(从物理设备)
IMO,磁盘上的二进制文件只是一个字节的海洋.在我看来,二进制文件不能具有状态相关的编码,因为它是一个二进制文件.我对"二进制广泛的流"的概念很模糊,如果它甚至可以应用于磁盘I/O.
我看到调用fseek(file, 0, SEEK_END)
串口流就像一个com端口,或者stdin
可能无法达到真正的目的,因为结束还没有确定.从而将问题缩小到物理文件.
[编辑]答案:与老年人(可能直到20世纪80年代后期)的关注.目前在2014年,Windows,POSIT特定和非异国他人:不是问题.
@Shafik Yaghmour提供了一个很好的参考,使用fseek和ftell来确定文件的大小是否有漏洞?.@Jerry Coffin将CP/M视为二进制文件并不总是具有精确的长度.(每个维基128字节的记录).
感谢@Keith Thompson的回答.
这一点解释了规范的"(因为可能有尾随空字符)"评论.
在您可能使用的任何系统上,二进制文件将是具有精确指定大小的8位字节序列.但并非所有系统都以这种方式存储文件,而且C标准经过精心设计,可以移植到具有不寻常特性的系统.
例如,符合要求的C实现可以在操作系统上运行,该操作系统将文件存储为512字节块的序列,而不指示最终块的多少字节是重要的.在这样的系统上,当创建二进制文件时,OS可能用零字节填充最后一个块的剩余部分.从这样的文件读取时,填充字节可能出现在输入中(即使它们从未显式写入文件),也可能被忽略(即使创建该文件的程序可能已明确写入) .
如果您正在从不可搜索的流中读取(例如键盘输入),那么fseek(file, 0, SEEK_END)
不会只给您一个不好的结果,它会通过返回非零结果来指示失败.(在符合POSIX的系统上,它返回-1并设置errno
; ISO C不需要它.)
在大多数系统上,fseek(file, 0, SEEK_END)
二进制文件将寻找文件的实际末尾(由确切地写入文件的字节数确定的位置),或返回明确的失败指示.如果你正在使用POSIX特定的功能,你可以安全地假设这种行为; 您可以对Windows和许多其他系统做出相同的假设.如果您希望您的代码100%可移植到异国情调的系统,您不应该假设二进制文件不会被额外的零字节填充.