C++的"最佳"输入文件格式?

Dig*_*lue 18 c++ sqlite json file-format xml-parsing

我正在开始研究一种新软件,最终需要一些强大且可扩展的文件IO.那里有很多格式.XML,JSON,INI等等.但是,总有一些优点和缺点,所以我想我会要求一些社区输入.

以下是一些粗略的要求:

  1. 格式是"标准"......如果我不需要,我不想重新发明轮子.它不一定是正式的IEEE标准,但你可以谷歌并获得一些新用户的信息,可能有一些超越vi的支持工具(编辑器).(虽然软件用户通常会精通计算机并且很乐意使用vi.)
  2. 轻松与C++集成.我不想让100mb库和三个不同的编译器来启动它.
  3. 支持表格输入(2d,n维)
  4. 支持POD类型
  5. 可以扩展,因为需要更多输入,可以很好地绑定变量等.
  6. 解析速度并不十分重要
  7. 理想情况下,尽可能易于书写(反映)
  8. 适用于Windows和Linux
  9. 支持合成(一个文件引用另一个文件来读取,依此类推.)
  10. 人类可读

在一个完美的世界中,我会使用一个只有头的库或一些干净的STL实现,但如果它运行良好,我可以利用Boost或一些小的外部库.

那么,您对各种格式有何看法?缺点?好处?

编辑

要考虑的选项?还有什么要补充的?

  • XML
  • YAML
  • SQLite的
  • Google协议缓冲区
  • 提升序列化
  • INI
  • JSON

mvp*_*mvp 18

有一种优秀的格式符合您的所有标准:

SQLite的!

请阅读文章有关使用SQLite作为应用程序的文件格式.另外,请观看 D. Richard Hipp(SQLite作者)关于这个话题的Google Tech Talk.

现在,让我们看看SQLite如何满足您的要求:

格式是"标准"

SQLite已成为大多数移动环境的首选格式,对于许多桌面应用程序(Firefox,Thunderbird,谷歌浏览器,Adobe Reader,您的名字).

轻松与C++集成

SQLite有标准的C接口,它只有一个源文件和一个头文件.还有C++包装器.

支持表格输入(2d,n维)

SQLite表是您可能想象的表格.要表示说三维数据,请使用列创建表x,y,z,value并将数据存储为一组行,如下所示:

x1,y1,z1,value1
x2,y2,z2,value2
...
Run Code Online (Sandbox Code Playgroud)

支持POD类型

我假设POD你的意思是普通旧数据,或BLOB.SQLite允许您按原样存储BLOB字段.

可以扩展,因为需要更多输入,可以很好地绑定变量

这是它真正闪耀的地方.

解析速度并不十分重要

但SQLite的速度非常棒.实际上,解析基本上是透明的.

理想情况下,尽可能易于书写(反映)

只是INSERT用来写和SELECT阅读 - 什么可以更容易?

适用于Windows和Linux

你打赌,还有所有其他平台.

支持合成(一个文件引用另一个文件来读取)

您可以将一个数据库附加到另一个数据库.

人类可读

不是二进制文件,但有许多优秀的SQLite浏览器/编辑器.我喜欢Windows 上的SQLite Expert Personal和Linux 上的sqliteman.Firefox还有SQLite编辑器插件.


SQLite为您提供免费的其他优势:

  • 数据是可索引的,这使得搜索速度非常快.您无法使用XML,JSON或任何其他纯文本格式执行此操作.

  • 即使数据量非常大,也可以部分编辑数据.您只需编辑一个值就不必重写几千兆字节.

  • SQLite是完全事务性的:它可以保证您的数据始终保持一致.即使您的应用程序(或整个计算机)崩溃,您的数据也会在下次第一次尝试连接数据库时自动恢复到上次已知的一致状态.

  • SQLite 逐字存储您的数据:您不必担心转义数据中的垃圾字符(包括嵌入字符串中的零字节) - 只需始终使用预准备语句,这就是使其透明所需的全部内容.在处理文本数据格式时,尤其是XML,这可能是一个很大且烦人的问题.

  • SQLite以Unicode格式存储所有字符串:( UTF-8默认)或UTF-16.换句话说,您无需担心文本编码或对数据格式的国际支持.

  • SQLite允许您以小块(实际上是逐行)处理数据,因此它在低内存条件下运行良好.对于任何基于文本的格式,这可能是一个问题,因为它们通常需要将所有文本加载到内存中以进行解析.当然,很少有高效的基于流的XML解析器,但一般来说,与SQLite相比,任何XML解析器都会非常贪婪.

  • SQLite表**是**你任意大小的数组,不是吗? (2认同)

Bob*_*phy 8

在XML和json上工作了很多,这是我对可扩展序列化格式的主观看法:

  • 格式是"标准":两者都是
  • 轻松与C++集成:两者都适用.在每种情况下,您可能最终会使用某种库来处理它.在Linux上,libxml2是标准的,而libxml ++是它的C++包装器; 你应该能够从你的发行版包管理器中获得这两个.要让那些在Windows上工作的人需要一些小的努力.对于json来说,Boost似乎有一些支持,但我还没有使用它; 我总是使用库来处理json.真的,图书馆的路线也不是很繁重.
  • 支持表格输入(2d,n维):两者均为
  • 支持POD类型:两者都适用
  • 可以扩展,因为需要更多的输入:两者都是 - 这对他们两个都是一个很大的优势.
  • 与变量绑定良好:如果你的意思是文件本身内部的一些方式说" 这段数据必须在我的程序中自动反序列化为这个变量",那么两者都没有.
  • 因为阅读容易编写(反映):取决于你使用的库,但根据我的经验肯定两者.(你实际上可以使用printf()编写json.)
  • 在Windows和Linux上运行良好:两者都适用,并且就此而言同样适用于Mac OS X.
  • 支持引用另一个文件的一个文件来读取:如果你的意思是类似于C#include,那么XML有一定的能力(例如文档实体),而json没有.
  • 人类可读:两者通常用UTF-8编写,并允许换行和缩进,因此可以是人类可读的.但是,我刚刚使用了一个479 KB的XML文件,所有这些都在一行上,所以我必须通过一个漂亮的打印机来运行它才能理解它.json也可能非常难以理解,但根据我的经验,它的格式通常比XML更好.

在开始新项目时,我通常更喜欢json; 它更紧凑,更易读.我可能选择XML over json的主要原因是,如果我担心接收格式错误的文档,因为XML支持自动文档格式验证,而您必须使用json编写自己的验证代码.


Dig*_*lue -6

就我的目的而言,我认为可行的方法是XML

  1. 该格式是一个标准,但允许随着程序需求的发展而修改和灵活地改变模式。
  2. 有几个库选项。有些较大(Xerces-C),有些较小(ezxml),但有很多选项,因此我们不会局限于单个提供商或非常具体的解决方案。
  3. 它可以支持表格输入(2d、n维)。这需要在“我们的”端进行更多的解析工作,并且可能是 XML 的最弱点。
  4. 支持 POD 类型:绝对支持。
  5. 可以随着需要更多输入而扩展,通过模式修改和解析器修改很好地绑定到变量等。
  6. 解析速度并不是非常重要,因此处理一个或多个文本文件不是问题。
  7. XML 可以通过编程方式编写,就像读取一样容易。
  8. 在 Windows 和 Linux 或任何其他支持 C 和文本文件的操作系统上运行良好。
  9. 支持合成(一个文件引用另一个文件来读取,等等。)
  10. 人类可读的许多文本编辑器(Sublime、vi 等)都支持开箱即用的语法突出显示。许多网络浏览器都能很好地显示数据。

感谢所有的反馈!我认为如果我们想要一个纯粹的二进制解决方案,Protocol Buffers 或 boost::serialization 可能是我们会选择的方式。

  • 我确实投了反对票。写下自己的答案,有效地抄袭其他人的答案,然后接受它作为答案,这种形式确实很糟糕,而且它不利于这里的激励制度。 (5认同)
  • 虽然我没有对此投反对票,但我会评论:在这样的情况下,由于您的答案没有提供其他答案未涵盖的解决方案,因此写下您所做的答案并接受它是一种不好的形式。更好地接受其他人的最佳答案(我认为你仍然可以改变),除非他们都没有任何好处......此外,除非你的答案实际上添加了一些有用的东西(这没有),否则最好写下你选择的解决方案作为评论。 (4认同)