如何在二进制文件上使用fread()将数据读入std::vector

How can I use fread() on a binary file to read the data into a std::vector?

本文关键字:数据 std vector 二进制文件 fread      更新时间:2023-10-16

我之前有一个问题的后续问题,这个问题已经得到了完美的回答。快速回顾一下,我在创建一个包含巨大数组的类时遇到了麻烦(堆栈溢出错误)。在回答中,一些用户建议我使用std::vector。

读取数据的函数如下所示:
Test()
{
   memset(myarray, 0, sizeof(myarray));
   FILE* fstr = fopen("myfile.dat", "rb");
   size_t success= fread(myarray, sizeof(myarray), 1, fstr);
   fclose(fstr);
}

对于一个myarray,它看起来像这样:

int myarray[45000000];

我的问题是:我怎样才能把它读成一个更可取的:

std::vector<int> myvector;

我搜索了谷歌,发现了多个答案,通常指向以下代码:

std::ifstream input("myfile.dat", std::ios::in | std::ifstream::binary);
std::copy(std::istream_iterator<int>(input), 
     std::istream_iterator<int>(), 
     std::back_inserter(myvector));

在实现这个之后,当调用myvector.size()时,我得到16(无论出于什么原因),并且访问向量元素会导致超出向量边界的立即崩溃。

那么我要怎么做才能做对呢?我曾经在某个地方读到,我可以简单地使用"旧"方法,然后将数组读入向量,但这似乎违背了首先使用向量的目的。

fread()读取您的文件二进制,而ifstream_iterator试图提取格式化的 int(如42)。

您想要resize您的vector和使用input.read(...)代替:

const size_t size = 45000000; // change this to the appropriate value
std::vector<char> myvector(size, 0);
std::ifstream input("myfile.dat", std::ios::in | std::ifstream::binary);
input.read(&myvector[0], myvector.size());

注意,您需要使用std::vector<char>,因为read期望第一个参数是char *。如果正确转换类型,可以使用其他类型T:

input.read(reinterpret_cast<char*>(&myvector[0]), myvector.size() * sizeof(T));

如果你正在使用c++,你应该尽量避免同时使用C FILE api——这样你就在正确的轨道上了。您遇到的问题是istream_iterator将输入读取为文本,而不是二进制-它期望ASCII数字。This This out:

std::vector<int> vec(45000000);
std::filebuf fb;
fb.open("myfile.dat", std::ios_base::in | std::ios_base::binary);
fb.sgetn((char*)&vec[0], vec.size() * sizeof(vec[0]));