翻译:Seeking and reading large files in a Linux C++ application

Stack overflow地址:Seeking and reading large files in a Linux C++ application - Stack Overflow


翻译:

我在使用标准 G++内置函数 ftell和 fseek遇到了整型溢出的问题,但是我猜我错了因为好像 ftell64和 fseek64是不可用的。我搜索过并且很多网页都指向使用带有 off64_t数据结构的 lseek,但是我没有找到任何示例关于 fseek的。现在我要读取的文件是一个16GB的CSV文件,期望是这个两倍的大小。

在不使用额外库的情况下,最直接的方法来实现一个类似 fseek/ftell数据结构是什么?我的程序现在使用的是标准的 GCC/G++库 4.X工作。


Answers1:

fseek64是一个C语言函数。为了保证它可用你必须定义 _FILE_OFFSET_BITS=64宏在包含系统头文件之前,这或多或少的定义 fseek表现的像 fseek64。或者在编译参数的时候这么做:gcc -D_FILE_OFFSET_BITS=64 ....

http://www.suse.de/~aj/linux_lfs.html有很好的概述关于大文件支持在linux上:

1.编译你的程序使用"gcc -D_FILE_OFFSET_BITS=64"。这将会强制所有的文件访问调用都使用 64位的变量。几种类型变化也是这样。off_t变成了 off64_t。因此总是使用正确的类型而不是使用上面那样。int代替 off_t。为了可移植性,其他平台你应该使用 getconf LFS_CFLAGS,它会返回 D_FILE_OFFSET_BITS=64 在Linux平台,但是可能返回其他的某些东西在其他平台,像 Solaris。对于链接文件,你应该使用link标志位被 getconf LFS_LDFLAGS提供的。在Linux系统上,你不需要特殊的链接标志位

2.定义 _LARGEFILE_SOURCE和 _LARGEFILE64_SOURCE。有了这些定义你可以直接使用 LFS函数像 open64。

3.在open大文件时使用 O_LARGEFILE标志位


Answers2:

如果你坚持使用 ISO C标准接口,使用 fgetpos()和 fsetpos()。然而,这些函数只对保存一个文件位置和稍后返回到相同位置有效。它们定义位置使用 fpos_t类型。它不需要是整数类型的数据结构。举个例子,在基于记录的系统上它可以是一个数据结构包含一个记录好和偏移量的数据结构。这可能过于有限。

POSIX定义了函数 ftello()和 fseeko(),它们使用off_t类型来表示位置。它需要是一个int类型,它的值是字节偏移量从文件开始的。你可以对它执行算术运算,也可以使用 fseeko()来执行相关的定位。这将会在 Linux和 POSIX系统上有效。

另外,编译带 -D_FILE_OFFSET_BITS=64选项(Linux/Solaris)。这将会定义 off_t是一个 64位的类型(如off64_t)来代替long类型,并重新定义使用文件偏移量作为64位偏移量版本的函数。这些是你编译64位程序时的默认值,不需要你做任何操作。


Answers3:

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

你试过 fgetpos和 fsetpos吗?它们为大文件而设计,通常实现使用 64位类型代替 fpos_t。

你可能感兴趣的:(翻译:Seeking and reading large files in a Linux C++ application)