【问题标题】:read big file with stream (up 8 GB) [duplicate]使用流读取大文件(最多 8 GB)[重复]
【发布时间】:2018-01-16 07:15:45
【问题描述】:

我想用流(ifstream 和 ofstream)读取文件(任何文件,无论大小)。

我用follow功能,这个功能适合中小文件

Struct StreamPacket
{
 long int startOffset;
 std::vector<char> data;
}
CONST int STREAM_BUFFER = 15000;
std::ifstream stream;

stream.open(path, std::ios::in | std::ios::binary | std::ios::ate);

if (!stream.is_open())
    return std::vector<StreamPacket>();


// create a vector to hold all the bytes in the file
std::vector<StreamPacket> wholePacket;
while (stream.is_open())
{
    StreamPacket fileStream;
    fileStream.startOffset = stream.tellg();
    // read the file
    std::vector<char> data(STREAM_BUFFER, 0);
    stream.read(&data[0], STREAM_BUFFER);
    fileStream.data = data;
    wholePacket.push_back(fileStream);
}

stream.close();

return wholePacket;

但我无法用它读取大文件(例如 8 GB),而且我在 while 循环中有错误,错误是:

Unhandled exception at 0x7703B782 in program.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x004FEEDC.

怎么了?我的问题出在哪里?

为了写,我使用这个函数:

void SaveToFile(CString path, CString filename, std::vector<StreamPacket> fileStream)
{
std::ofstream outfile(path + filename, std::ios::out | std::ios::binary);

if (!outfile.is_open())
    return;

for (size_t i = 0; i < fileStream.size(); i++)
{
    outfile.write(&fileStream[i].data[0], fileStream[i].data.size());
}
int a = 10;

//outfile.write(&fileStream[0], fileStream.size());
outfile.close();
}

正确吗?

谢谢你的帮助

【问题讨论】:

  • 在错误发生之前有多少次迭代?
  • 也许你没有足够的内存来存储整个文件?
  • 您的应用程序是 32 位的吗?看起来您正在尝试一次将整个文件加载到内存中。 32 位应用程序的最大内存为 4GB。使用流的目的是在读取时处理数据。
  • 您的应用程序似乎内存不足。您仍然可以读取文件,但无法一次将全部内容保存在内存中。
  • @WooWapDaBug 如果应用程序是 32 位,则 64 位机器无济于事。您仍然有 4GB 的上限(实际上只有大约 3.5GB)。

标签: c++


【解决方案1】:

除了32位的限制,代码还有两大缺陷。

a) 你的代码有很多错误,所以修复它需要时间.. (例如 Struct StreamPacket 必须是小写的“struct”..

b) 自 1970 年以来,当 RAM 非常有限时,文件背后的逻辑是读取块、处理它、释放/重用缓冲区和循环。

它允许使用非常有限的小空间来管理甚至 TB 的数据。

所以主要思想是重新考虑您的代码以使用此逻辑。 编写起来可能会更复杂,但认为像在 JS/Web 应用程序中那样管理文件是错误的

使用大文件作为内存的建议:内存映射文件。

(例如:mmap() vs. reading blocks

或者windows下也有类似的功能。

【讨论】:

  • Struct错误意味着OP发布了假代码时,真的很难评论代码。
猜你喜欢
  • 1970-01-01
  • 2013-02-03
  • 1970-01-01
  • 2013-11-02
  • 2017-10-02
  • 1970-01-01
  • 2013-08-15
  • 2012-01-05
  • 1970-01-01
相关资源
最近更新 更多