18

我正在开发一款新软件,最终需要一些强大且可扩展的文件 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
4

4 回答 4

18

有一种出色的格式可以满足您的所有标准:

SQLite!

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

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

格式是“标准”

SQLite 已成为大多数移动环境和许多桌面应用程序(Firefox、Thunderbird、Google Chrome、Adobe Reader 等等)的首选格式。

与 C++ 轻松集成

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

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

SQLite 表就像你想象的那样是表格的。要表示 3 维数据,请创建包含列的表x,y,z,value并将数据存储为一组行,如下所示:

x1,y1,z1,value1
x2,y2,z2,value2
...

支持 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 解析器,但一般来说,任何 XML 解析器与 SQLite 相比都会非常占用内存。

于 2013-02-05T04:27:39.103 回答
8

在对 XML 和 json 进行了相当多的工作后,以下是我对两者作为可扩展序列化格式的相当主观的看法:

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

开始新项目的时候,我一般比较喜欢json;它更紧凑,更易于阅读。我可能会选择 XML 而不是 json 的主要原因是如果我担心接收格式错误的文档,因为 XML 支持自动文档格式验证,而您必须使用 json 编写自己的验证代码。

于 2013-02-05T05:18:13.037 回答
4

查看谷歌缓冲区。这可以满足您的大部分要求。

从他们的文档中,高级步骤是:

在 .proto 文件中定义消息格式。
使用协议缓冲区编译器。
使用 C++ 协议缓冲区 API 来写入和读取消息。

于 2013-02-05T04:27:01.847 回答
-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 可能是我们会采用的方式。

于 2013-02-08T19:25:44.493 回答