Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Создать большой файл XML 400мб+ (ошибка out of memory) / 17 сообщений из 17, страница 1 из 1
12.03.2020, 14:14
    #39936669
Valery_B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Добрый день, пытаюсь создать большой XML файл, и вылезает соответствующая ошибка.
Когда при формировании файла размер программы в памяти вырастает до 3.8ГБ, после этого программа падает(что логично).
Итоговый файл при этом получается чуть более 400мб.

TXMLDocument
DOM Provider = Omnixml
RAD Studio 10.3 Rio

Примерно такой код:
Код: pascal
1.
2.
3.
4.
5.
6.
while not DataSet.Eof do
 begin
  ANode:=Node.AddChild('Название').Text:=DataSet.FieldByName('Name').AsString;
  ANode.AddChild...
  DataSet.Next;
 end;


В реальности, код чуть более сложный (с подчинёнными узлами), тэгов добавляется около 20 и их название заметно длиннее.
Получается совсем не понятное соотношение - файл 400мб, а в памяти = 3.8 гб.
Учитывая, что имена тэгов в XML дублируются(открывающий и закрывающий), реально он должен занимать почти в 2 раза меньше памяти.

Кто нибудь сталкивался с таким и можно ли это исправить ?
Переходить на х64 ?
...
Рейтинг: 0 / 0
12.03.2020, 14:17
    #39936671
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Можно воспользоваться SAX-парсером от MS.. И писать через него... Он входит в MSXML 6.0
Но тогда теряется кроссплатформенность...
...
Рейтинг: 0 / 0
12.03.2020, 14:29
    #39936679
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Я, может, чего-то не знаю, но как парсер поможет при создании?

По сабжу: кмк, тут только писать самостоятельно. Можно с привлечением движка, конечно - например, генерить N узлов, получать их XML текст и скидывать в файл - но склеивать куски воедино уже самому.
...
Рейтинг: 0 / 0
12.03.2020, 14:37
    #39936686
vavan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Valery_B
Кто нибудь сталкивался с таким
с подобным, в частности при экспорте девэксом грида в xlsx
Valery_B
можно ли это исправить ?
отказаться от создания всей структуры в памяти и тем более формирования tmemorystream (или string) с финальным содержимым когда конечная задача лишь скинуть в файл
Valery_B
Переходить на х64 ?
тоже конечно "решение"
...
Рейтинг: 0 / 0
12.03.2020, 14:55
    #39936693
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
X-Cite
Можно воспользоваться SAX-парсером от MS.. И писать через него..
Все хорошо, кроме того, что это исключительно читающий парсер
...
Рейтинг: 0 / 0
12.03.2020, 14:58
    #39936694
figli
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Valery_B,

а зачем тебе DOM при создании? создавай построчно текстовый файл
...
Рейтинг: 0 / 0
12.03.2020, 14:59
    #39936695
LocksmithPC
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Valery_B

Итоговый файл при этом получается чуть более 400мб.


Сколько будут весить данные в csv/dbf?
...
Рейтинг: 0 / 0
12.03.2020, 15:03
    #39936696
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Valery_B
Итоговый файл при этом получается чуть более 400мб.
Я создавал такие файлы чистым MSXML.

А вообще, по моим наблюдениям, комфортный размер итогового XML 10-15 мегабайт. Так что я порекомендую разбить большой файл на кусочки
Valery_B
Получается совсем не понятное соотношение - файл 400мб, а в памяти = 3.8 гб.
Учитывая, что имена тэгов в XML дублируются(открывающий и закрывающий), реально он должен занимать почти в 2 раза меньше памяти.
Не должен. Кроме имени у узла есть еще куча других полей. Пространство имен, список атрибутов, список детей, родитель...
...
Рейтинг: 0 / 0
12.03.2020, 15:04
    #39936697
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
figli
а зачем тебе DOM при создании? создавай построчно текстовый файл
Совет так себе. Как минимум, нужно учитывать кодировку и экранирование спец-символов
...
Рейтинг: 0 / 0
12.03.2020, 15:38
    #39936709
x1ca4064
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Valery_B

Примерно такой код:
Код: pascal
1.
2.
3.
4.
5.
6.
while not DataSet.Eof do
 begin
  ANode:=Node.AddChild('Название').Text:=DataSet.FieldByName('Name').AsString;
  ANode.AddChild...
  DataSet.Next;
 end;


В реальности, код чуть более сложный (с подчинёнными узлами), тэгов добавляется около 20 и их название заметно длиннее.
Кто нибудь сталкивался с таким и можно ли это исправить ?
Переходить на х64 ?


Если текст ноды, выводимой для данной записи не зависит от других записей/нод, то итоговый XML можно представить так:
<Шапка>
<Табличная часть>
<Подвал>

соответственно, необходимо написать функцию RecordToXmlStr, которая для данной записи возвращает её XML текст. Тогда все будет примерно так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
WriteLn(f,sHead);
while not DataSet.Eof do
begin
  WriteLn(f,RecordToXmlStr(DataSet));
  DataSet.Next;
end;
WriteLn(f,sTail);


В RecordToXmlStr не забыть вставить конвертацию всяких '<','>','&' и пр.
...
Рейтинг: 0 / 0
12.03.2020, 17:18
    #39936756
Valery_B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
X-Cite
Можно воспользоваться SAX-парсером от MS.. И писать через него... Он входит в MSXML 6.0
Но тогда теряется кроссплатформенность...

Не совсем понял что это.
Как это сделать ?
Можно пример на TXMLDocument.Create ?
_Vasilisk_
Так что я порекомендую разбить большой файл на кусочки

Ну, если бы у меня был выбор, тогда я бы это сделал вообще в Json
_Vasilisk_
Пространство имен, список атрибутов, список детей, родитель...

Родитель это ссылка в памяти в 4 байта, int32. Неймспейс - это часть имени в ноде.


Формировать построчно нельзя, т.к. это будет решение конкретно этой задачи, а не универсальное решение.
И там есть подчинённые узлы.
...
Рейтинг: 0 / 0
12.03.2020, 17:22
    #39936757
Valery_B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
И ещё заметил.
Когда открываю файл 400МБ через TXMLDocument, он уже не есть столько памяти.
И туда спокойно можно делать .AddChild
...
Рейтинг: 0 / 0
12.03.2020, 17:30
    #39936763
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Valery_B
Неймспейс - это часть имени в ноде.
Нет
...
Рейтинг: 0 / 0
12.03.2020, 17:30
    #39936764
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
1. Сгенерить пустой документ в виде строк XML
2. Записать префикс (строки до первой записи, например, <?xml...?><Records>)
3. while not DS.EOF
3.1. serialize(DS.CurrentRecord, xmlDoc)
3.2. sNodeXML := xmlDoc['Records'].['Record'].XML
3.3. WriteFile(sNodeXML)
3.4. xmlDoc['Records'].ChildNodes.Clear
4. Записать постфикс (строки после записи, например, например, </Records>)
...
Рейтинг: 0 / 0
12.03.2020, 17:36
    #39936767
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
или еще вариант - генерить по документу на каждую запись, опять же получать xml только основного узла и встраивать его в пишущийся файл. Сложнее, но можно распараллелить сериализацию и запись в файл
...
Рейтинг: 0 / 0
12.03.2020, 18:15
    #39936796
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
http://www.kluug.net/oxml.php

Используйте OXml direct writer.

Память не тратит вообще.
...
Рейтинг: 0 / 0
13.03.2020, 13:53
    #39937087
figli
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать большой файл XML 400мб+ (ошибка out of memory)
Valery_B,

не нужен при создании файла DOM, раз ты данные линейным курсором получаешь, не надо себе проблемы выдумывать, он отжирает памяти в 10 раз больше данных.
подчиненные ноды - сортируй датасет правильно и все в строки уложится, а если у тебя mssql - так просто оттуда готовый xml забери.
кодировка и экранирование спецсимволов - это три строки кода.
да, и по скорости и по памяти быстрее ничего не будет, и файл хоть в гигабайты создавай, собственно для этого и совет по собственному опыту. для мелочи можно почудить с dom, но как более-менее большие данные пойдут, то заснет все.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Создать большой файл XML 400мб+ (ошибка out of memory) / 17 сообщений из 17, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]