如何序列化 QMap
How do you serialize a QMap?
我正在尝试学习如何使用以下代码在窗口应用程序中序列化 QMap 对象:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QString>
#include <QDataStream>
#include <QMap>
#include <QDebug>
void write ()
{
QString filename = "Z:/snippets.txt";
QFile myFile (filename);
if (!myFile.open(QIODevice::WriteOnly))
{
qDebug() << "Could not write " << filename;
return;
}
QMap<QString,QString> map;
map.insert("one","this is 1");
map.insert("two","this is 2");
map.insert("three","this is 3");
QDataStream out (&myFile);
out.setVersion(QDataStream::Qt_5_3);
out<<map;
myFile.flush();
myFile.close();
}
QMap<QString,QString> read ()
{
QString filename = "Z:/snippets.txt";
QFile myFile (filename);
QMap<QString,QString> map;
QDataStream in (&myFile);
in.setVersion(QDataStream::Qt_5_3);
if (!myFile.open(QIODevice::WriteOnly))
{
qDebug() << "Could not read " << filename;
return (map);
}
in >> map;
myFile.close();
return(map);
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnSave_clicked()
{
write();
}
void MainWindow::on_btnLoad_clicked()
{
QMap<QString,QString> map;
map = read();
QMapIterator<QString,QString> i(map);
//do other stuff
}
btnSave 调用的 write()
函数确实保存了 QMap。我可以在片段中看到数据.txt。我可以在调试器中看到,但是,read()
函数没有为 map
变量分配任何内容。我错过了什么?
正确的QMap
序列化和反序列化代码如下:
主.cpp
#include <QString>
#include <QFile>
#include <QMap>
#include <QDataStream>
#include <QDebug>
void write()
{
QString filename = "snippets.txt";
QFile myFile(filename);
if (!myFile.open(QIODevice::WriteOnly))
{
qDebug() << "Could not write to file:" << filename << "Error string:" << myFile.errorString();
return;
}
QMap<QString, QString> map;
map.insert("one", "this is 1");
map.insert("two", "this is 2");
map.insert("three", "this is 3");
QDataStream out(&myFile);
out.setVersion(QDataStream::Qt_5_3);
out << map;
}
QMap<QString,QString> read()
{
QString filename = "snippets.txt";
QFile myFile(filename);
QMap<QString, QString> map;
QDataStream in(&myFile);
in.setVersion(QDataStream::Qt_5_3);
if (!myFile.open(QIODevice::ReadOnly))
{
qDebug() << "Could not read the file:" << filename << "Error string:" << myFile.errorString();
return map;
}
in >> map;
return map;
}
int main()
{
write();
qDebug() << read();
return 0;
}
main.pro
TEMPLATE = app
TARGET = main
QT = core
SOURCES += main.cpp
构建和运行
qmake && make && ./main
输出
QMap(("one", "this is 1")("three", "this is 3")("two", "this is 2"))
您遇到了几个问题:
- 完全忽略错误代码和字符串
这使得你很难揭示真正的问题。
- 使用 QIODevice::WriteOnly 打开读取时
这是没有正确错误报告的情况下隐藏的问题。这里的问题是,当您打开文件仅用于写入时,任何后续读取操作都会自然产生空结果。通过 QDataStream
执行此操作时,它有点隐藏,但是如果您在直接阅读 QFile 实例时快速浏览一下 QIODevice 文档,它会变得更加清楚错误打开模式下面发生了什么:
最多将 maxSize 字节从设备读取到数据中,并返回读取的字节数。如果发生错误,例如尝试从以 WriteOnly 模式打开的设备读取时,此函数将返回 -1。
如果您检查了错误,这将变得更加清晰。公平地说,在您的情况下,在此简单代码段中可以接受操作之前共享文件而不关闭它。在这种情况下,你会使用类似重新搜索到开头和QIODevice::ReadWrite的东西。话虽如此,这只是另一种方式。
- 不正确地使用 qDebug((
这只是一个旁注,但您明确添加了空格,而 qDebug(( 已经为您这样做了。
- 序列化时不必要地刷新文件。
这是多余的,因为它是在通过类析构函数关闭文件描述符时自动完成的。
- 不必要地关闭文件对象
这是由适当的 RAII 自动完成的。如果文件仍处于打开状态,则 desctructor 将为您关闭它。由于您离开了函数的范围,因此在堆栈上构造文件对象时,将自动为文件对象调用析构函数。
可能是因为您在读取函数中以WriteOnly
打开文件。正确的形式是:
if (!myFile.open(QIODevice::ReadOnly))
{
qDebug() << "Could not read " << filename;
return (map);
}
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 如何反序列化数组?
- 如何使用提升序列化?
- 序列化多晶型接口
- 如何序列化 QMap