大文件支持无法在C编程中工作
我正在尝试编译一个共享对象(最终在Python中使用ctypes)。 用于构建对象的命令行是:
gcc -Wall -O3 -shared -Wl,-soname,borg_stream -lm -m128bit-long-double -fPIC \ -D_FILE_OFFSET_BITS=64 -o borg_stream.so data_stream.c data_types.c \ file_operations.c float_half.c channels.c statistics.c index_stream.c helpers.c
该库可在32位操作系统上正确构建,并且可以满足小文件的需要。 但是,对于大于4GB的文件,它无法进行unit testing。 此外,它在执行fseek / ftell时将errno设置为EOVERFLOW。 但是,如果我printf sizeof(off_t),它返回8.如果我删除-D_FILE_OFFSET_BITS=64
,那么它打印4.所以似乎-D_FILE_OFFSET_BITS
正在正常工作。
为什么大文件支持仍然不起作用? 我究竟做错了什么?
将选项-D_LARGE_FILE_SOURCE=1
添加到gcc编译中。
fseek64
是一个C函数。 要使其可用,您必须在包含系统标头之前定义_FILE_OFFSET_BITS = 64。 这或多或少会定义fseek
的行为与fseek64
。 或者您可以在编译器参数中执行此操作,例如gcc -D_FILE_OFFSET_BITS = 64,您已经在执行此操作。
http://www.suse.de/~aj/linux_lfs.html有一个关于linux上大文件支持的好信息:
使用gcc -D_FILE_OFFSET_BITS=64
编译程序。 这会强制所有文件访问调用使用64位变体。 有几种类型也会改变,例如off_t
变为off64_t
。 因此,始终使用正确的类型并在C代码中不使用例如int
而不是off_t
是很重要的。 为了便于与其他平台一起使用,您应该使用getconf LFS_CFLAGS
,它将在Linux平台上返回-D_FILE_OFFSET_BITS=64
,但可能会返回其他内容,例如在Solaris上。 对于链接,您应该使用通过getconf LFS_LDFLAGS
报告的链接标志。 在Linux系统上,您不需要特殊的链接标志。 定义_LARGEFILE_SOURCE
和_LARGEFILE64_SOURCE
。 使用这些定义,您可以直接使用open64
等LFS函数。 使用带打开的O_LARGEFILE
标志来操作大文件。
希望这可以帮助。
使用fseeko和ftello。 不是fseek和ftell。 当然也没有名称中包含64的任何function。
fseek和ftell接受一个32位的int
,所以它被强制转换,你失去了解决大于4GB空间的能力。 而是使用fseeko64
和ftello64
这需要很long
。