【问题标题】:Reading and writing a std::vector into a file correctly正确读取和写入 std::vector 到文件中
【发布时间】:2012-09-04 13:11:56
【问题描述】:

这就是重点。如何写入和读取包含 std::vector 的二进制文件?

我在想这样的事情:

//============ WRITING A VECTOR INTO A FILE ================
const int DIM = 6;
int array[DIM] = {1,2,3,4,5,6};
std::vector<int> myVector(array, array + DIM);
ofstream FILE(Path, ios::out | ofstream::binary);
FILE.write(reinterpret_cast<const char *>(&myVector), sizeof(vector) * 6);
//===========================================================

但我不知道如何读取这个向量。因为我认为以下是正确的,但事实并非如此:

ifstream FILE(Path, ios::in | ifstream::binary);
FILE.read(reinterpret_cast<const char *>(&myVector), sizeof(vector) * 6);

那么,如何进行操作呢?

【问题讨论】:

    标签: c++ file-io stl iostream stdvector


    【解决方案1】:

    尝试使用ostream_iterator/ostreambuf_iteratoristream_iterator/istreambuf_iterator 和 STL copy 方法:

    #include <algorithm>
    #include <iostream>
    #include <iterator>
    #include <vector>
    
    #include <fstream> // looks like we need this too (edit by π)
    
    std::string path("/some/path/here");
    
    const int DIM = 6;
    int array[DIM] = {1,2,3,4,5,6};
    std::vector<int> myVector(array, array + DIM);
    std::vector<int> newVector;
    
    std::ofstream FILE(path, std::ios::out | std::ofstream::binary);
    std::copy(myVector.begin(), myVector.end(), std::ostreambuf_iterator<char>(FILE));
    
    std::ifstream INFILE(path, std::ios::in | std::ifstream::binary);
    std::istreambuf_iterator iter(INFILE);
    std::copy(iter.begin(), iter.end(), std::back_inserter(newVector));
    

    【讨论】:

    • 嗨,我认为它应该在相应的复制行中读取 ostreambuf_iterator(FILE)。
    • 该向量的类型参数是什么?它是字符的向量吗?还是整数?如果它不是字符向量,如何将其复制写入字符的输出迭代器?它只是将每个项目下转换为单个字节吗?
    • std::istreambuf_iterator iter(INFILE);不适用于 MSVC2016?
    • @user1024 我已经发布了这个程序的完整版here
    • 我同意 user1024——VS 2013 编译器不喜欢将 ifstream 作为迭代器实例的参数。
    【解决方案2】:

    使用boost::serialization

    如果您不想使用boost - 写入大小和vector

    size_t sz = myVector.size();
    FILE.write(reinterpret_cast<const char*>(&sz), sizeof(sz));
    FILE.write(reinterpret_cast<const char*>(&myVector[0]), sz * sizeof(myVector[0]));
    

    【讨论】:

      【解决方案3】:

      你可以使用

      #include <boost/serialization/vector.hpp>
      

      序列化你的向量。在此处阅读教程:http://www.boost.org/libs/serialization/doc/tutorial.html#stl `

      【讨论】:

      • 值得一提的是,Boost.Serialization 可能会显着影响构建时间和二进制文件大小。因此,如果 TS 只需要将向量保存到文件中,使用序列化将是矫枉过正。
      【解决方案4】:

      在阅读vector之前,您应该调整它的大小:yourVector.size(numberOfElementsYouRead)

      此外,sizeof(vector&lt;your_type&gt;) 只是vector 对象内部实现的大小;矢量元素大小为sizeof(std::vector&lt;your_type&gt;::value_type)

      然后这样读:

      file.read(reinterpret_cast<char *>(&myVector[0]), sizeof(vector<int>::element_type) * element_count); 
      

      【讨论】:

      • 好的,那么,你认为我选择的方式( FILE.read(reinterpret_cast(&myVector), sizeof(vector) * 6); )是正确的吗?
      • @facunvd 1) 不要转换为const; 2)根据上述正确计算尺寸。当然,@Platinum Azure 提出的方法要好得多。
      【解决方案5】:

      我使用了 data() 方法返回一个可用于读取和写入的地址这一事实。

      // 假设 outf 是一个可写的文件指针(二进制)。 // 将 myVector.size() 写入文件,然后

      fwrite(myVector.data(), sizeof(decltype(myVector)::value_type), myVector.size(), outf);
      

      阅读:

      // 从文件中读取 MyVector.size() 作为 nv,inpf 是读取文件指针

      MyVector.resize(nv);
      fread(MyVector.data(), sizeof(decltype(MyVector)::value_type), nv, inpf);
      

      在文件 io 中坚持旧方法,但请忽略它(即使它可能会激怒你:))。

      一个缺点是这种方式不支持字节顺序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多