大文件支持无法在C编程中工作

时间:2013-01-26 04:21:42

标签: c large-files

我正在尝试编译一个共享对象(最终在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的文件进行单元测试。另外,它在执行fseek / ftell时将errno设置为EOVERFLOW。但是,如果我printf sizeof(off_t),则返回8.如果我删除-D_FILE_OFFSET_BITS=64,则打印4.所以看起来-D_FILE_OFFSET_BITS正在正常工作。

为什么大文件支持仍无效?我做错了什么?

3 个答案:

答案 0 :(得分:4)

将选项-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标志来操作大文件。

希望这有帮助。

答案 1 :(得分:3)

使用fseeko和ftello。不是fseek和ftell。当然也不是任何名称为64的函数。

答案 2 :(得分:1)

fseek和ftell接受一个32位的int,因此它被强制转换,你失去了解决大于4GB空间的能力。而是使用fseeko64ftello64,其中long