【问题标题】:Binary stream or something like this to save class like std::vector to a file?二进制流或类似的东西将 std::vector 之类的类保存到文件中?
【发布时间】:2010-11-25 16:05:11
【问题描述】:

我不擅长 IOstream 库,因为我已经习惯了 stdio 和这种东西的生活,但是我遇到了一个希望在 IOstream 中解决的问题,但我发现它可能不是。所以我对标准 C++ 库还很陌生,但对 C++ OOP/Classes 等还是很熟悉。

所以我不能使用类似的代码

printf (stream, "...", C);

如果 C 是聚合类型,因为我无法创建新的格式字符串选项,例如 %mytupe。我也不能指望

的正确行为
fwrite/fread (&C, sizeof(C), 1, stream)

如果 T 包含指针字段,因为 fwrite/fread 将保存/加载指针的值,而不是存储在指针所指的内存中的值:

class MyClass
   {...
    private:
       {typename} Tp* Data;
   } C;

我不太在意第一个限制,因为我可以编写一个函数,将我的每个类的对象转换为文本字符串,即使最后一个不能轻易解决,它也可以工作。例如,我尝试创建一个将每个类保存到二进制文件的函数,但我遇到了很多工作人员的问题,比如模板部分专业化的运气等等(很重要)。

厌倦了在重写标准代码(如自己的字符串和文件持有者类)时犯错误和错误,我希望学习(终于!)标准(由聪明的人编写并经过良好测试:) 库对我有帮助,因为我读了很多标准 C++ 库解决使用流的第一个问题。我可以重载 operator > 等等,以确保我的类将被正确地保存到文本文件或从文本文件中读取。但是对我来说更重要的二进制文件呢?

如果我想将像vector这样的类对象保存到二进制文件中,我应该怎么做? > 的使用完全失败,因为它说向量没有重载运算符 >,但即使它有它也会产生文本数据。

员工喜欢

vector <MyClass> V;
...
ofstream file ("file.bin", ios::binary);

int size1 = ;
file.write((const char*)&V.size(), sizeof(V.size()));
file.write((const char*)&V[0], V.size() * sizeof(MyClass));

不适合(并且与使用 fwrite 没有太大区别),因为它保存指针字段的值(地址),但不保存存储在那里的数据(另外,如果我将“二维”向量声明为向量怎么办> ??)。因此,如果向量运算符 重载

template <class T> vector
  {public:
   ...    
     ostream operator << () const
        {ostream s;
         for (uint32_t k = 0; k < size(); k++)
            s << s << this->operator[] (k);
         return s;
        }
   private:
      T* Data;
  };

并且如果每个 T::operator

(我知道,我知道,应该有迭代器,但也许我犯了一个更严重的错误,因为完全误解了流?反正我只是在谈论想法。)

嗯,这是一种将数据转换为文本的方法,而不是获取存储在内存中的二进制数据,但我知道可以编写一个接口以相同的方式处理二进制数据(也许不使用 > 只是函数名,但可以肯定)!问题是:它是在标准 C++ 库还是在其他地方(另一个 C++ 开源库)完成的?是的,是的,在一行中正确地将向量写入文件。 (如果它没有包含在标准 C++ 中,我会感到非常惊讶,因为如果人们想要使用多维动态数组,他们如何将他们工作的数据保存到文件中?)

【问题讨论】:

    标签: c++ iostream


    【解决方案1】:

    您正在寻找“序列化”一词,并且您可能希望为此目的使用 Boost::Serialization 库。

    【讨论】:

    • 好吧,我害怕第三方库。还没有学过标准库,还需要学别的……std真的缺少这么重要的特性吗?大多数人使用 boost 来保存数据吗?
    • 所以,我已经了解了序列化是如何工作的,并且可能它可以完成我需要的一切,但是二进制存档是一个没有记录和推荐的东西。但令人惊讶的是,保存的二进制存档文件不仅包含一些额外的字节(希望它的数量不会很大程度上取决于有效数据的数量),而且还包括来自 boost aka text 'serialization::archive 的 'human-readable' "hello" ' 在二进制文件的开头。大声笑我有点困惑,每个人都会看到我使用了 boost。
    • @Nick:“二进制”数据有很多变化,很难标准化。 C++ 标准没有尝试。 Boost 相当普遍,但对于 JPEG 二进制数据,您将使用 JPEG 特定库。
    • 哦...我在 boost 中找到了 multi_dimension 数组,并且很高兴这是我非常需要的东西。什么? Boost不为其提供序列化吗?真讽刺!我很沮丧。
    • @MSalters,如果我们不使用 Boost,您是否知道为什么以下行不起作用? file.write((const char*)&amp;V, V.size() * sizeof(MyClass)); 请注意,我考虑使用 (const char*)&amp;V,而不是使用 (const char*)&amp;V[0]
    猜你喜欢
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    相关资源
    最近更新 更多