Ошибка при загрузке больших файлов с помощью setContent (& amp; file) в парсере qt DOM xml

Я сталкиваюсь со странной проблемой, которую не могу решить. Кажется, ни у кого нет этой проблемы. При загрузке небольшого XML-файла (4 МБ) все нормально, и программа работает нормально, но когда я пытаюсь загрузить больший файл (200 МБ), программа вылетает без ошибок (даже в режиме отладки). Он также не распечатывает сообщения об ошибках, так как программа вылетает до их вызова. Спасибо за помощь.

Журнал ошибок от создателя 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();

Решение:

Активируйте раздел подкачки или получите больше оперативной памяти, программа зависает, потому что на компьютере не хватает памяти. Обновления оставлены в вопросе только для того, чтобы документировать мои дальнейшие действия.

Обновить:
Я установил все на другой машине. Теперь я получаю вывод:

Ошибка: ошибка разбора в строке 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 действительными, и они являются. Итак, какие-нибудь новые предложения? Пока я застрял

Update2:
Сначала спасибо за ваши ответы! Одна отчаянная попытка была:

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 Parser: 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>

Я хочу перестроить точки пути, для которых необходимы значения lat, lon из узлов. Для этого я хочу иметь возможность сопоставить путь ID с идентификатором узла и получить значения в пути. Является ли Sax-парсер лучшим решением для этого? Я работал с деревом DOM, я мог бы легко пройти через «узлы» и сопоставить идентификаторы без повторного анализа полного XML. Я использую Ubuntu и с новой настройкой qt5. Я получил i5 2-го поколения и 8 ГБ оперативной памяти, которые заполнены во время обработки большого файла. Один запуск в режиме релиза требует 50 минут на 1000 трасс с 5-50 узлами.

1

Решение

Пакет Qt XML и QDomDocument не должен использоваться с очень большими документами XML.

Предмет QDomDocument сохраняет всю структуру XML-документа в оперативной памяти. Это решающий порог 200MB для размера файла XML, так как с такими файлами QDomDocument можешь использовать 2GB или ОЗУ.

Доступные выпуски Qt4 для Windows построены с 32-битными компиляторами. Таким образом, это предел для таких приложений, например Сколько памяти может получить доступ к 32-битному процессу в 64-битной операционной системе?

В целом, все большие XML-документы не должны загружаться в ОЗУ. Такие документы должны быть обработаны потоковые парсеры.

С другой стороны, если документ XML не намного больше, чем 200MB и проект уже работает с QDomDocument и на компьютере достаточно оперативки (8GB - 16GB) можно скомпилировать проект с использованием 64-битных компиляторов. В этом случае Qt4 должен быть скомпилирован вручную. Также Release сборка может использовать в два раза меньше оперативной памяти, чем Debug,

1

Другие решения

Решение состоит в том, чтобы активировать раздел подкачки или получить больше оперативной памяти, программа зависла, потому что на компьютере не было / не было оперативной памяти.
Еще лучшим решением является использование парсера SAX.

Проблема времени выполнения: используйте карты вместо векторов. Время выполнения уменьшилось до ~ 20 секунд для большого файла.

0

По вопросам рекламы [email protected]