大文件支持在C编程中不起作用

问题描述 投票:2回答:3

我正在尝试编译共享对象(最终在带有ctypes的Python中使用)。用于构建对象的命令行为:

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在正确地执行其工作。

为什么大文件支持仍然不起作用?我在做什么错?

c large-files
3个回答
5
投票

将选项-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。通过这些定义,您可以直接使用LFS功能,例如open64。将O_LARGEFILE标志与open一起使用可对大文件进行操作。

希望这会有所帮助。


3
投票

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


2
投票

fseek() and ftell()接受32位的fseek(),因此将其强制转换,您将失去处理大于4GB的空间的能力。而是使用带ftell()intfseeko64()

© www.soinside.com 2019 - 2024. All rights reserved.