在Linux C ++应用程序中查找和读取大文件

时间:2009-06-23 22:43:49

标签: c++ c linux gnu large-files

我使用G ++中的标准 ftell fseek 选项遇到整数溢出,但我想我错了,因为它似乎 ftell64 fseek64 不可用。我一直在搜索,许多网站似乎使用 lseek off64_t 数据类型引用,但我没有找到任何引用等于 fseek 的内容的示例。我现在正在阅读的文件是16GB + CSV文件,期望至少翻倍。

没有任何外部库,实现与 fseek / ftell 对相似的结构的最简单方法是什么?我的应用程序现在可以使用4.x的标准GCC / G ++库。

5 个答案:

答案 0 :(得分:27)

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。因此,始终使用正确的类型并且不使用例如正确的类型是很重要的。 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 :(得分:10)

如果您想坚持使用ISO C标准接口,请使用fgetpos()fsetpos()。但是,这些功能仅对保存文件位置以及稍后返回相同位置有用。它们使用类型fpos_t表示位置,它不需要是整数数据类型。例如,在基于记录的系统上,它可以是包含记录中的记录号和偏移量的结构。这可能太有限了。

POSIX定义函数ftello()fseeko(),它们使用off_t类型表示位置。这必须是整数类型,并且该值是从文件开头偏移的字节。您可以对其执行算术,并可以使用fseeko()执行相对搜索。这适用于Linux和其他POSIX系统。

此外,使用-D_FILE_OFFSET_BITS=64(Linux / Solaris)进行编译。这将off_t定义为64位类型(即off64_t)而不是long,并将使用文件偏移的函数重新定义为采用64位偏移的版本。在编译64位时这是默认设置,因此在这种情况下不需要。

答案 2 :(得分:5)

fseek64()不是标准的,编译器文档应该告诉你在哪里找到它。

您是否尝试过fgetposfsetpos?它们是为大文件设计的,实现通常使用64位类型作为fpos_t的基础。

答案 3 :(得分:5)

您是否尝试将 _FILE_OFFSET_BITS 预处理器符号设置为 64 fseeko()

这将为您提供 fseek()类似的界面,但其偏移参数类型为 off_t ,而不是 long 。设置 _FILE_OFFSET_BITS = 64 会使 off_t 成为64位类型。

同样适用于 ftello()

答案 4 :(得分:2)

使用fsetpos(3)fgetpos(3)。它们使用fpos_t数据类型,我相信它保证能够保存至少64位。