1

我遇到了一个我无法解决的奇怪问题。似乎没有人有这个问题。在加载一个小的 XML 文件(4mb)时,一切都很好,程序运行正常,但是当我试图加载一个更大的文件(200mb)时,程序崩溃而没有任何错误(即使在调试模式下)。它也不会打印出错误消息,因为程序在调用之前崩溃了。感谢您的帮助。

QT 创建者的错误日志是:

程序意外结束。C:/Parser [路径]/XmlDOM 崩溃

代码:

QFile file("./file.osm");
qDebug() << file.exists();
qDebug() << file.size();

QString errorStr;
int errorLine;
int errorColumn;

QDomDocument document;

if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
    qDebug() << "Failed to open file";
    return -1;
}
else
{
    if(!document.setContent(&file, false, &errorStr, &errorLine, &errorColumn)) //here the programm crashes
    {
        std::cerr << "Error: Parse error at line " << errorLine << ", "
                          << "column " << errorColumn << ": "
                          << qPrintable(errorStr) << std::endl;
       return -1;
    }
    qDebug() << file.isReadable(); //with small files this becomes true 
    file.close();
    } 
QDomElement root = document.firstChildElement();

解决方案:

激活交换分区或获得更多 RAM,程序崩溃,因为 PC 已/已用完 RAM。将更新留在问题中只是为了记录我的进一步步骤。

更新: 我在另一台机器上安装了所有东西。现在我得到一些输出:

错误:第 1 行第 1 列的解析错误:文件意外结束

现在有趣的是,即使是小文件也无法正常工作并返回错误。经过一些挖掘,有些人将文件的路径设置错了,所以我检查了我的路径。

qDebug() << "File exists: " << file.exists(); 
qDebug() << "File path: " << QFileInfo(file).absoluteFilePath();
qDebug() << "File size: " << file.size();    

这将返回:true,/path/to/file/file.osm,正确的大小

我还检查了我的 XML 文件是否有效,它们是否有效。那么有什么新的建议吗?到目前为止我卡住了

更新2: 首先感谢您的回答!一次绝望的尝试是:

else{
  document.setContent(&file); //passed and worked, funny
}
qDebug() << file.isReadable(); 
file.close();

这最终适用于新设置中较大和较小的文件:

else
{

    if(!document.setContent(&file))
    {
       std::cerr << "Error: Open file "<< std::endl;
       return -1;
    }
    qDebug() << file.isReadable(); 
    file.close();

为什么我使用 DOM 解析器:XML 结构是这样的:

<osm>
    <node id ="1" lat="value", lon="value" />
    <node id ="2" lat="value", lon="value" />
    <node id ="3" lat="value", lon="value" />

    <way id="12345">
      <nd ref ="1"/>
      <nd ref ="2"/>
      <nd ref ="3"/>
    </way>
</osm>

我想重建节点的纬度,经度值的路点是必要的。为此,我希望能够将方式 ref id 与节点 id 匹配,并将值放入方式中。Sax 解析器是更好的解决方案吗?我对 DOM 树进行了测试,我可以轻松地通过“节点”并匹配 id,而无需再次解析完整的 XML。我正在使用 Ubuntu 并使用新设置 qt5。我有一个 i5 第二代和 8GB 的​​ RAM,在处理大文件时它们已满。在发布模式下运行一次需要 50 分钟 für 1000ways with 5-50 个节点。

4

2 回答 2

1

Qt XML 包QDomDocument不应该用于非常大的 XML 文档。

该对象QDomDocument将整个 XML 文档结构保存在 RAM 中。它是200MBXML 文件大小的关键阈值,因为此类文件QDomDocument可以使用2GB或 RAM。

适用于 Windows 的可用 Qt4 版本是使用 32 位编译器构建的。因此,对于此类应用程序是有限制的,例如32 位进程在 64 位操作系统上可以访问多少内存?

通常不应将整个大型 XML 文档加载到 RAM。此类文档应由流解析器处理。

另一方面,如果 XML 文档不大于200MB并且项目已经在使用QDomDocument并且 PC 上有足够的 RAM ( 8GB - 16GB),则可以使用 64 位编译器编译项目。在这种情况下,应该手动编译 Qt4。此外Releasebuild 使用的 RAM 可能比Debug.

于 2015-11-07T12:16:13.263 回答
0

解决方案是激活交换分区或获得更多 RAM,程序崩溃是因为 PC 已/已用完 RAM。更好的解决方案是使用 SAX 解析器。

运行时问题:使用地图而不是向量。对于一个大文件,运行时间缩减到约 20 秒。

于 2015-11-25T10:28:49.997 回答