我试图依靠stat(2)
系统调用来确定文件的大小,以便为其分配适当的缓冲区。更具体地说,我使用的是stat.st_size
系统调用填充的结构。
但在调试过程中,我注意到足够大的文件会引起一些麻烦:struct stat
手册页中定义的内容如下所示:
struct stat {
// ...
off_t st_size; /* total size, in bytes */
// ...
};
wherest_size
被定义为off_t
which 解析为 a long int
,令我惊讶的是,而不是unsigned long int
.这当然会导致一个问题,即足够大的文件会溢出整数并导致该值表示负数,而我在检查中没有考虑到这一点(为什么会st_size
是负数?)
另外,根据手册页,EOVERFLOW
当块数无法在 中表示时,系统调用应该返回错误off_t
,但在我使用 gcc 9.3 的本地 ubuntu 中 - 大小大于0x80000000
字节的文件不会引发此类错误。此外,“正确”的方法是进行编译,-D_FILE_OFFSET_BITS=64
将off_t
字段从 32 位整数扩展为 64 位整数,这可以帮助您管理更大的文件。
这当然解决了我的问题,但我仍然想知道,为什么将定义保留为有符号整数?
答案1
off_t
是由 POSIX 定义, 并且是
用于文件大小。
它需要能够表示负值,因为它不仅用于文件大小,还用于文件偏移量(因此得名),并且偏移量可以为负数(在文件中向后移动)lseek
例如)。
您可能想知道为什么size_t
不能用它来代替;但它用于测量对象的大小,特别是 C 对象,而不是文件大小。