将 std::vector<int> 保存到文件

Save an std::vector<int> to file

我注意到,在使用时:

std::vector<int> v(100000);
...
std::ofstream outfile("outfile.dat", std::ios::out | std::ofstream::binary);
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(outfile));
outfile.close();

my std::vector<int> 没有序列化为原始字节数据(每个 int 4 个字节)而是序列化为字符串,即将每个整数的字符串表示形式保存到磁盘,这是我不想要的.

如何将std::vector<int>保存为二进制数据?

(注意:在学习新方法之前,我想用标准的 C++03 来学习它)。

std::ostream_iterator 使用其 operator<< 将值写入流。元素的编写就像您对向量的每个成员使用 outfile << value,这意味着将值转换为文本。

因此,您要做的是定义一个 class 以二进制表示形式将自身序列化到流中,例如:

std::copy(v.begin(), v.end(), std::ostream_iterator<BinaryInt>(outfile));
                                                    ^^^^^^^^^

现在您必须定义 BinaryInt 类型,以便它可以由 int 值构造,但通过 operator<< 适当地序列化自身:

struct BinaryInt
{
    int value;
    BinaryValue(int v): value(v) {}
    friend std::ostream& operator<<(std::ostream& str, BinaryInt const& bi)
    {
        // convert bi.value into a binary representation.
        // Note C++ does not define a specific size for int.
        // Nor does it define an endianess.
        // Nor does it define a specific representation.
        // So to be cross platform/OS/compiler you will need to define these
        // and convert the integer into this representation.
        //
        // return str.write(<data>, <size>);
        //
        // If this is just a test the following would work
        // but is extremely brittle for the long term.

        return str.write(reinterpret_cast<const char*>(&bi.value), sizeof(bi.value));
    }
};

写入二进制数据,使用std::ostream::write() instead of std::ostream_iterator(内部使用operator<<,从而格式化输出),如:

std::vector<int> v(100000);
...
std::ofstream outfile("outfile.dat", std::ofstream::binary);
outfile.write(reinterpret_cast<const char*>(v.data() /* or &v[0] pre-C++11 */), sizeof(int) * v.size());
outfile.close();

我可以推荐一种使用 Protobufs 的更明智的方法吗?代码我就不敲了,不过如果你在做项目,就不要重新发明轮子了。

使用 protobuf 可以让您将数据 "type" 与数据一起保存,并且可以帮助您轻松地扩展代码。