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

发布于 2024-07-25 11:56:00 字数 353 浏览 9 评论 0原文

我使用 G++ 内的标准 ftellfseek 选项遇到整数溢出,但我想我错了,因为似乎 ftell64fseek64 不可用。 我一直在搜索,许多网站似乎引用使用 lseekoff64_t 数据类型,但我没有找到任何引用等于 fseek 的示例。 现在我正在读取的文件是 16GB 以上的 CSV 文件,预计至少是这个大小的两倍。

在没有任何外部库的情况下,实现与fseek/ftell对类似的结构的最直接方法是什么? 我的应用程序现在使用 4.x 的标准 GCC/G++ 库运行。

I am running into integer overflow using the standard ftell and fseek options inside of G++, but I guess I was mistaken because it seems that ftell64 and fseek64 are not available. I have been searching and many websites seem to reference using lseek with the off64_t datatype, but I have not found any examples referencing something equal to fseek. Right now the files that I am reading in are 16GB+ CSV files with the expectation of at least double that.

Without any external libraries what is the most straightforward method for achieving a similar structure as with the fseek/ftell pair? My application right now works using the standard GCC/G++ libraries for 4.x.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

握住我的手 2024-08-01 11:56:00

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 标志与 open 一起使用可对大文件进行操作。

fseek64 is a C function. To make it available you'll have to define _FILE_OFFSET_BITS=64 before including the system headers That will more or less define fseek to be actually fseek64. Or do it in the compiler arguments e.g.
gcc -D_FILE_OFFSET_BITS=64 ....

http://www.suse.de/~aj/linux_lfs.html has a great overviw of large file support on linux:

  • Compile your programs with "gcc -D_FILE_OFFSET_BITS=64". This forces all file access calls to use the 64 bit variants. Several types change also, e.g. off_t becomes off64_t. It's therefore important to always use the correct types and to not use e.g. int instead of off_t. For portability with other platforms you should use getconf LFS_CFLAGS which will return -D_FILE_OFFSET_BITS=64 on Linux platforms but might return something else on e.g. Solaris. For linking, you should use the link flags that are reported via getconf LFS_LDFLAGS. On Linux systems, you do not need special link flags.
  • Define _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE. With these defines you can use the LFS functions like open64 directly.
  • Use the O_LARGEFILE flag with open to operate on large files.
夏花。依旧 2024-08-01 11:56:00

如果您想坚持使用 ISO C 标准接口,请使用 fgetpos()< /code>fsetpos()< /a>. 但是,这些函数仅适用于保存文件位置并稍后返回到同一位置。 它们使用 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 位时的默认设置,因此在这种情况下不需要。

If you want to stick to ISO C standard interfaces, use fgetpos() and fsetpos(). However, these functions are only useful for saving a file position and going back to the same position later. They represent the position using the type fpos_t, which is not required to be an integer data type. For example, on a record-based system it could be a struct containing a record number and offset within the record. This may be too limiting.

POSIX defines the functions ftello() and fseeko(), which represent the position using the off_t type. This is required to be an integer type, and the value is a byte offset from the beginning of the file. You can perform arithmetic on it, and can use fseeko() to perform relative seeks. This will work on Linux and other POSIX systems.

In addition, compile with -D_FILE_OFFSET_BITS=64 (Linux/Solaris). This will define off_t to be a 64-bit type (i.e. off64_t) instead of long, and will redefine the functions that use file offsets to be the versions that take 64-bit offsets. This is the default when you are compiling for 64-bit, so is not needed in that case.

烂人 2024-08-01 11:56:00

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

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

fseek64() isn't standard, the compiler docs should tell you where to find it.

Have you tried fgetpos and fsetpos? They're designed for large files and the implementation typically uses a 64-bit type as the base for fpos_t.

无法回应 2024-08-01 11:56:00

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

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

对于 ftello() 也是如此。

Have you tried fseeko() with the _FILE_OFFSET_BITS preprocessor symbol set to 64?

This will give you an fseek()-like interface but with an offset parameter of type off_t instead of long. Setting _FILE_OFFSET_BITS=64 will make off_t a 64-bit type.

The same for goes for ftello().

如歌彻婉言 2024-08-01 11:56:00

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

Use fsetpos(3) and fgetpos(3). They use the fpos_t datatype , which I believe is guaranteed to be able to hold at least 64 bits.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文