如何在没有fseek和ftell的情况下获得ANSI C中的文件大小?

mat*_*ots 13 c size file filesize

在寻找找到文件大小的方法时FILE*,我发现这篇文章反对它.相反,它似乎鼓励使用文件描述符和fstat.

但是我的印象是fstat,open文件描述符一般都不那么便携(经过一​​些搜索,我发现了这个效果).

有没有办法在ANSI C中获取文件的大小,同时保持与文章中的警告一致?

Car*_*rum 14

在标准C中,fseek/ ftelldance几乎是城里唯一的游戏.你做的其他任何事情至少在某种程度上取决于你的程序运行的特定环境.不幸的是,舞蹈也有你所链接的文章中描述的问题.

我猜你总是可以读出文件中的所有内容,直到EOF并保持跟踪 - fread()例如.

  • 请注意,虽然ISO C没有定义二进制文件的结尾,但POSIX确实如此,并且所有真实的,1980年后的C实现都同意这个问题.二进制文件具有确切的大小,您可以相对于末尾进行搜索. (6认同)
  • ..也在我的回答中. (2认同)

R. *_*des 6

该文章声称fseek(stream, 0, SEEK_END)是一种不定义的行为,引用了一个不合时宜的脚注.

脚注出现在处理面向广播的流的文本中,这些流是对它们执行的第一个操作的流是对宽字符的操作.

这种未定义的行为源于两个段落的组合.首先§7.19.2/ 5说:

- 二进制宽向导流具有归因于文本和二进制流的文件定位限制.

文本流(第7.19.9.2/4节)对文件定位的限制是:

对于文本流,要么offset是零,要么offset是早先成功调用ftell与同一文件关联的流上的函数返回的值,并且whence应该是SEEK_SET.

这使得面向广泛的流的fseek(stream, 0, SEEK_END)未定义行为.对于面向字节的流,没有像§7.19.2/ 5这样的规则.

此外,当标准说:

二进制流不需要有意义地支持值为的fseek调用.whenceSEEK_END

这并不意味着它的未定义行为.但是如果流支持它,那没关系.

显然这是允许二进制文件具有粗粒度粒度,即大小是多个磁盘扇区而不是多个字节,因此允许未指定数量的零神奇地出现在二进制文件的末尾.SEEK_END在这种情况下无法得到有意义的支持.其他示例包括管道或无限文件/dev/zero.但是,C标准无法区分这些情况,因此如果您想考虑这一点,就会遇到与系统相关的调用.