【问题标题】:How to process large files (4+ GB) correctly and portably in C++?如何在 C++ 中正确且可移植地处理大文件(4+ GB)?
【发布时间】:2019-01-16 12:56:17
【问题描述】:

在我的职业生涯中,我从来不需要处理像我的应用程序这样大的文件,我有点难过。

我的应用程序会在一个文件中记录很多东西,而且它可能会增长到几个千兆字节。该应用程序必须在 Windows(7 及以上)和所有现代 Linux(内核 4 及以上)上运行,适用于 32 位和 64 位机器

我尝试使用fread 和朋友,因为它们是可移植的,但他们都使用long。我考虑将文件拆分为多个 2 GB 的文件,以便继续使用签名的long,但这似乎有点过多的处理开销。

是否有一组可移植的库函数可以帮助完成这项任务,还是我必须围绕平台 API 编写一个精简的包装器?


编辑:回答评论中的一些问题。

  1. 这是一个二进制数据文件。
  2. 我不需要将它全部加载到内存中,但必须寻找偏移量。
  3. 关于使用 fstream,基于this 似乎行不通,所以我没有考虑在内。

【问题讨论】:

  • 您是否遇到过std::fstream 和 co 处理这种大小的文件的问题?
  • 您必须一次将整个内容读入内存吗?如果不是,我认为您想要拆分文件是完全正确的。
  • @Tom 我不同意 - 理想情况下,不需要在文件系统上拆分文件。当然,您不会一次将整个文件读入内存,但无论如何您都不应该这样做
  • 把整个文件映射到内存呢?只有映射的访问内存区域才会真正导致页面错误,因此系统将只保留应用程序所需的物理内存。与提供系统的相比,stl 提供的内容非常原始。

标签: c++ linux windows cross-platform large-files


【解决方案1】:

我认为你不能做到便携,但这种解决方法可能会有所帮助(未经测试)。

#include <stdint.h>
#include <stdio.h>
#ifdef _MSC_VER
inline int seek64( FILE *stream, int64_t offset, int origin )
{
    return _fseeki64( stream, offset, origin );
}
#else
#define _LARGEFILE64_SOURCE
#include <sys/types.h>
#include <unistd.h>
inline int seek64( FILE *stream, int64_t offset, int origin )
{
    const int fd = fileno( stream );
    return (int)lseek64( fd, offset, origin );
}
#endif

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 2013-11-19
    相关资源
    最近更新 更多