Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Qt C++;_C++_Json_Qt - Fatal编程技术网

C++ 在Qt C++;

C++ 在Qt C++;,c++,json,qt,C++,Json,Qt,我需要序列化和解析项目中的多个对象,以便在需要时保存/加载它们 我的对象将具有完全相同的组件:一个QString名称、一个整数id、一个QString描述和两个整数x,y。 我需要这样的东西: {"name":"toto", "id":"42", "description":"tata", "x":"20", "y":"50"} 因此,我将构建我的QJsonObject,如下所示: QJsonObject json; json["id"] = object_to_serialize.get_i

我需要序列化和解析项目中的多个对象,以便在需要时保存/加载它们

我的对象将具有完全相同的组件:一个QString名称、一个整数id、一个QString描述和两个整数x,y。 我需要这样的东西:

{"name":"toto", "id":"42", "description":"tata", "x":"20", "y":"50"}
因此,我将构建我的QJsonObject,如下所示:

QJsonObject json;
json["id"] = object_to_serialize.get_id();
json["name"] = object_to_serialize.get_name();
json["description"] = object_to_serialize.get_description();
json["x"] = object_to_serialize.get_x();
json["y"] = object_to_serialize.get_y();
QJsonDocument filedoc(json);
file.write(filedoc.toJson);`
{"name":"toto", "id":"42", "description":"tata", "x":"20", "y":"50"}
{"name":"toto2", "id":"44", "description":"tata2", "x":"25", "y":"547"}  
{"name":"toto3", "id":"46", "description":"tata3", "x":"21", "y":"580"}
在文件中,它将显示如下:

QJsonObject json;
json["id"] = object_to_serialize.get_id();
json["name"] = object_to_serialize.get_name();
json["description"] = object_to_serialize.get_description();
json["x"] = object_to_serialize.get_x();
json["y"] = object_to_serialize.get_y();
QJsonDocument filedoc(json);
file.write(filedoc.toJson);`
{"name":"toto", "id":"42", "description":"tata", "x":"20", "y":"50"}
{"name":"toto2", "id":"44", "description":"tata2", "x":"25", "y":"547"}  
{"name":"toto3", "id":"46", "description":"tata3", "x":"21", "y":"580"}
我的serialiser将接受对象的参数savefile name,并将对象转换为QJsonObject。然后需要读取该文件以检查是否存在具有相同id的对象。如果它在这里,它将需要替换它,如果它不在,它将附加它

我有点迷失在序列化选项和如何阅读之间

我应该制作一个内部有多个QJsonObject的QJsonArray还是制作一个带有QJsonArray的QJsonObject

当我阅读它时,我需要检查id;但是a会吗

foreach(object.value["id"] == 42)
  //create the QJsonObject from the one with 42 and change it with the new data
要解析对象,而不是所有对象,该怎么办?有更好的办法吗


提前感谢您的回答。

您可以拥有一个json对象数组,每个对象都有一个ID,这样您就可以解析相关的对象了

虽然您也可以解析所有这些文件并将它们添加到地图中,但只要您没有非常繁重的文件,就可以了

void parseJson(const QString &data)
{
    QJsonDocument doc = QJsonDocument::fromJson(data.toUtf8());

    if (doc.isNull())
    {
        war("invalid json document");
        return;
    }


    QJsonArray jsonArray = doc.array();
    foreach (const QJsonValue & value, jsonArray) {
        QJsonObject obj = value.toObject();
        if (obj.contains("id"))
        {
            if (obj["id"].toInt() == yourId) parseObject(obj);
        }
    }
}


void parseObject(const QJsonObject &obj)
{
    if (obj.contains("valueA")) valueA = obj["valueA"].toDouble();
    if (obj.contains("valueB")) valueB = obj["valueB"].toDouble();
}
如果您的文件不是太大,这将很好地工作


更大的文件 现在,如果您有一个非常大的文件,那么将其全部加载到内存中并对其进行解析可能是一个问题

由于您的结构总是相同且非常简单,因此JSON可能不是最佳选择,一种更有效的方法是使用您自己的解析器(或者可能使用一些现有的解析器)读取文件并将其作为流进行处理


另一种方法是,每行有一个JSON条目,前面有一个带有固定数字的ID。在QHash查找中加载它,然后只从文件中读取感兴趣的id,并且只解析一小部分

// This code is not tested and is just to show the principle.
#define IDSIZE 5
QHash<int64, int64> m_lookup; // has to be global var

// For very large file, this might take some time and can be done on a separate thread.
// it needs to be done only once at startup (given the file is not modified externally)
void createLookup(const QString &fileName)
{
    QFile inputFile(fileName);
    if (inputFile.open(QIODevice::ReadOnly))
    {
       QTextStream in(&inputFile);
       while (!in.atEnd())
       {
          int position = in.pos(); // store the position in the file
          QString line = in.readLine();
          int id = line.mid(0,IDSIZE).toInt(); // 5 digit id (like 00001, 00002, etc...
          m_lookup[id] = position + IDSIZE;
       }
       inputFile.close();
    }
}

QString getEntry(const QString &fileName, int64 id)
{
     if (m_lookup.contains(id))
     {
        QFile inputFile(fileName);
        if (inputFile.open(QIODevice::ReadOnly))
        {
            inputFile.seek(m_lookup[id]);
            QString data = inputFile.readLine();
            inputFile.close();
            return data;
        } else {
            return QString(); // or handle error
        }
     } else {
        return QString(); // or handle error
     }
}

// use example
QString data = getEntry(id);
if (data.length() > 0)
{
    QJsonDocument doc = QJsonDocument::fromJson(data.toUtf8());
    if (!doc.isNull())
    {
        // assign your variables
    }
}
这种方法的优点是,它只读取感兴趣的条目,并且避免了为了获取特定条目而必须在内存中加载MB或GB的数据


这可以通过在文件开头存储一个查找表来进一步改进。

您的目标是将数据保存在一个文件中,其中每一行都是json,然后能够通过获取相同的对象来读取数据,对吗?是的,你有没有一种方法可以有效地序列化这些对象;我的意思是,我需要一些时间拿一件这样的东西来改变它(更改其名称、描述……我可以使用您的解析方法直接在JsonArray中更改它并重写整个文件吗?我不确定是否理解您的问题。使用最后一种方法,您可以选择一项,修改它并重写它,而无需更改文件的其余部分。(如果条目长度不同,系统仍需修改文件,在这种情况下,可以使用填充)。