我需要将一些数据结构存储到 SQL 数据库中。这些数据可能会有所不同,所以我不知道数据库必须有哪些字段。我即将将数据结构编码为 XML 或 JSON 对象,然后将其放入 SQL 数据库。但它无法工作,所以我需要serialization,因为问题在于对该结构进行编码。
我可以使用哪个库/工具/方法将数据结构序列化/反序列化为文本?假设一个由一些整数、一些 Unicode 字符串和一些布尔值组成的数据结构。
提前谢谢了!
因为问题在于对该结构进行编码。
Qt 不能自动序列化事物,因此您必须编写某种例程来保存/加载数据。确切的解决方案取决于您的要求以及您将如何使用数据。
你应该考虑的事情:
推荐:
细节:
如果您正在与某物进行通信,那么您将被与您与之通信的事物所使用的任何格式所困。那可能是 json 或 xml,因为各种脚本语言经常可以很容易地读取它们中的任何一个
如果数据应该是人类可读的,那么您有以下选项:纯文本、json 或 xml,具体取决于数据格式/复杂性。(ini 在您的场景中不起作用,因为QSettings支持它并不会真正序列化到随机内存位置。xml/json)可以存储树状结构,但 json 在 Qt 4 中只能通过外部使用依赖,而xml 读取器/写入器需要努力才能掌握它。
如果您想存储非人类可读且仅由您的应用程序使用的私有数据(仅由您的应用程序使用),您几乎可以使用任何您想要的数据,包括二进制格式。
最简单的方法是手动将其转储到QByteArray
+中,因为无论字节顺序如何,都可以保证二进制数据将正确加载到任何平台上(只要您不将其转储为原始内存块)。如果数据是具有固定数量始终存在的组件的类似结构的简单数组,那将可以正常工作。QDataStream
QDataStream
如果数据是树状的并且具有可选节点(即键值对树,其中值可以是另一棵树)并且键可能存在也可能不存在,那么您将使用处理这些键/值对的库或例程树木。在 Qt 4 中是QVariantMap
和 xml(通过QXmlStreamWriter
/ QXmlStreamReader
)。Qt 5 也有 json 支持。在有多种解决方案可用的情况下,实施起来花费最少的内置解决方案会胜出。从每个值读取命名字段QVariantMap
需要 1 行代码 + 大约 10 行代码的辅助函数,它还支持所有 Qt 4 类型。
QVariantMap
从某种意义上说,它具有其他 json 的显着优势,因为它本机支持所有 Qt 类型作为值。即您可以轻松地转储QColor
, QPoint
, 以及您在其中注册的类型。您可以存储在 QVariant 中的任何内容,都可以存储在 中QVariantMap
,然后可以在一行代码中将其序列化到 QDataStream 或从 QDataStream 序列化。
另一方面,Json 具有可以在脚本语言中加载的“标准”数据格式的优势。这是以它只支持 6 种基本类型为代价的。
Qt 4 本身不支持 Json,虽然有 QJson,但添加外部依赖项并不总是一个好主意,因为你要照看它们。如果您使用的是 Qt 4 并且确实需要 json 支持,那么升级到 Qt 5 可能是有意义的。
您如何处理数据库中的这些数据?如果您想在其他程序或语言中使用它,那么您的数据需要是可读的,您可以使用 QXmlStreamWriter/Reader 或 QJsonDocument(两者都带有 QByteArray)。
如果您不想在程序之外使用您的数据,您可以使用 QDataStream 将它们写入 QByteArray。
这将类似于下面的代码。
QByteArray data;
QDataStream stream(&data);
stream << yourClasses;
sqlQuery.bindValue(data);
您只需要在要序列化的类中添加流运算符:
QDataStream &operator<<(QDataStream &, A const&);
QDataStream &operator>>(QDataStream &, A &);
这是一个冗长而详细的答案,但重点在这里。Qt 5.2 有一个示例,您可以根据“SaveGame”示例如何使用 Qt 实现所有这些,该示例也进行序列化和反序列化。它基本上是为不可玩的游戏角色做的。它还QSaveFile
用于将信息安全地保存到所需的文件中。为方便起见,您可以在此处找到示例文档的 url:
http://doc-snapshot.qt-project.org/qdoc/qtcore-savegame-example.html
几天前我刚刚用 Qt5 的 json 解析器解决了这个问题。我建议看看以下课程:
QJsonDocument
:http: //qt-project.org/doc/qt-5.1/qtcore/qjsondocument.htmlQJsonObject
:http: //qt-project.org/doc/qt-5.1/qtcore/qjsonobject.htmlQJsonArray
:http: //qt-project.org/doc/qt-5.1/qtcore/qjsonarray.htmlQJsonParseError
:http: //qt-project.org/doc/qt-5.1/qtcore/qjsonparseerror.htmlQJsonValue
:http: //qt-project.org/doc/qt-5.1/qtcore/qjsonvalue.html如果您打算使用 Qt 4,您将需要使用该QJson
库,但请注意,它比基于性能的 Qt 5 json 解析器慢很多。在这里你可以找到蒂亚戈的基准:
https://plus.google.com/108138837678270193032/posts/7EVTACgwtxK
json 格式随心所欲地支持字符串、整数和布尔值,所以它应该适合你。在这里您可以找到如何序列化和反序列化此类类型的签名:
bool toBool(bool defaultValue = false) const
double toDouble(double defaultValue = 0) const
QString toString(const QString & defaultValue = QString()) const
QJsonValue(bool b)
QJsonValue(double n)
QJsonValue(const QString & s)
在这里您可以找到关于 Qt 5 中 json 支持的摘要页面:
http://doc-snapshot.qt-project.org/qt5-nosubdir/json.html
请注意,Qt 5 的 json 在内部保存为一种非常有效的二进制表示形式,因此本质上您也可以使用它而不是文本表示形式。这取决于您的确切情况。实际上,对于 Qt 4,如果需要,您甚至可以向后移植这些类,因为它们与 Qt 5 紧密相关。对于 BlackBerry 开发而言,实际上可能是如此,因为我们在那里与 Qt 4 苦苦挣扎,我们非常需要来自的 json 解析器Qt。