代码之家  ›  专栏  ›  技术社区  ›  Sean Edwards

用C++/STL存储二进制数据的“正确”方法

  •  43
  • Sean Edwards  · 技术社区  · 16 年前

    一般来说,在C++中存储二进制数据的最佳方式是什么?据我所知,这些选项可以归结为使用字符串或向量<char>s(我将省略char*s和malloc()s的可能性,因为我专门指的是C++)。

    4 回复  |  直到 16 年前
        1
  •  43
  •   Doug T.    16 年前

      std::vector<char> vect;
      ...
      send(sock, &vect[0], vect.size());
    

    它会很好的工作。

    实际上,您可以像对待任何其他动态分配的字符缓冲区一样对待它。你可以上下扫描寻找神奇的数字或图案。您可以就地对其进行部分解析。对于从套接字接收,您可以非常轻松地调整其大小以附加更多数据。

    缺点是调整大小效率不高(谨慎地调整大小或预分配),从数组前端删除也将非常无效。例如,如果您需要频繁地从数据结构的前端一次弹出一个或两个字符,那么在此处理之前复制到deque可能是一种选择。这需要一个副本,而deque内存不是连续的,所以不能只传递一个指向C API的指针。

    总之,在深入研究之前,先了解数据结构及其折衷,然而,我在一般实践中看到的通常是字符向量。

        2
  •  8
  •   Tamas Demjen Tamas Demjen    16 年前

    std::string的最大问题是当前的标准不能保证其底层存储是连续的。然而,并没有已知的STL实现中字符串是不连续的,所以在实践中它可能不会失败。事实上,新的C++0x标准将通过强制std::string使用连续缓冲区(如std::vector)来解决这个问题。

    另一个反对字符串的论点是,它的名称表明它包含一个字符串,而不是二进制缓冲区,这可能会给阅读代码的人造成混淆。

    也就是说,我也推荐vector。

        3
  •  7
  •   Head Geek    16 年前

    std::string

    一个“指针”,我昨天在一段代码中收到了一个尖锐的提示:当从二进制数据块创建字符串时,使用 std::string(startIter, endIter) 构造函数窗体,而不是 std::string(ptr, offset, length) form——后者假设指针指向C样式的字符串,并忽略第一个零字符之后的任何内容(它复制“最多”指定的字符串) length 字符)。

        4
  •  3
  •   Todd Gardner    16 年前

    您当然应该使用一些char容器,但是您想要使用的容器取决于您的应用程序。

    上面Doug讨论了存储字符的适当stl容器。您需要哪一个完全取决于您的用例。如果您只是持有一个迭代的数据块,而不需要任何特殊的查找、追加/删除或拼接需要,那么我更喜欢vector,它比std::string更清楚您的意图,许多库和函数都认为std::string持有以null结尾的c样式字符串。