Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Сохранение JSON объекта  [new]
Miracle9
Member

Откуда:
Сообщений: 102
При попытке сохранить большой JSON объект (40+ мбайт данных)
SL.Add(TJson.Format(JObject));

выскакивает ошибка out of memory.
Кто нибудь сталкивался, как решить?
31 окт 18, 00:11    [21719664]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Dmitry Arefiev
Member

Откуда:
Сообщений: 9647
Miracle9
40+ мбайт данных

Где, чего, когда ... Могли перед этим вызовом быть 1.5 гиг текста загружены ...
Лучше пример кода привести.
31 окт 18, 00:17    [21719670]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Miracle9
Member

Откуда:
Сообщений: 102
При закрытии формы
procedure TFMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
  SL: TStringList;
  JObject: TJSONObject;
  ToolArray: TJSONArray;
  ToolObject: TJSONObject;

  DataArray: TJSONArray;
  DataObject: TJSONObject;

  i, j: integer;
begin
  SL := TStringList.Create;
  try
    JObject := TJSONObject.Create;
    if (Tools.Count > 0) then
    begin
      ToolArray := TJSONArray.Create;
      for i := 0 to Tools.Count - 1 do
      begin
        ToolObject := TJSONObject.Create;
        ToolObject.AddPair('name', TJSONString.Create(Tools[i].name));
        ToolObject.AddPair('symbol', TJSONString.Create(Tools[i].symbol));
        ToolObject.AddPair('link', TJSONString.Create(Tools[i].link));

        if (Tools[i].Data.Count > 0) then
        begin
          DataArray := TJSONArray.Create;
          for j := 0 to Tools[i].Data.Count - 1 do
          begin
            DataObject := TJSONObject.Create;
            DataObject.AddPair('date', TJSONNumber.Create(Tools[i].Data[j].Date));
            DataObject.AddPair('open', TJSONNumber.Create(Tools[i].Data[j].Open));
            DataObject.AddPair('high', TJSONNumber.Create(Tools[i].Data[j].high));
            DataObject.AddPair('low', TJSONNumber.Create(Tools[i].Data[j].low));
            DataObject.AddPair('close', TJSONNumber.Create(Tools[i].Data[j].close));
            DataArray.AddElement(DataObject);
          end;
          ToolObject.AddPair('Data', DataArray);
        end;
        ToolArray.AddElement(ToolObject);
      end;
      JObject.AddPair('Tools', ToolArray);
    end;

    SL.Add(TJson.Format(JObject));
    SL.SaveToFile(ExtractFilePath(Application.ExeName) + 'DATA.json');
  finally
    FreeAndNil(SL);
    FreeAndNil(JObject);
  end;
end;
31 окт 18, 00:22    [21719672]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Котовасия
Member

Откуда:
Сообщений: 1187
Miracle9,

а зачем ты строку, которую возвращает Format(), перед сохранением в TStringList загоняешь?
31 окт 18, 00:29    [21719675]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Dmitry Arefiev
Member

Откуда:
Сообщений: 9647
TJsonTextWriter
31 окт 18, 00:34    [21719677]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Miracle9
Member

Откуда:
Сообщений: 102
Котовасия
Miracle9,

а зачем ты строку, которую возвращает Format(), перед сохранением в TStringList загоняешь?

Чтобы сохранить её в файл.
31 окт 18, 01:02    [21719690]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Котовасия
Member

Откуда:
Сообщений: 1187
Miracle9,

а по-другому - никак, только после копирования в стриглист?

Ты хоть проверь, доходит ли дело до формирования выходной строки. Может, у тебя все на Format() падает.
Почему не используешь superobject, если такой ленивый. Там и в файл, и в поток сохранение есть, и быдлокодить в два раза меньше.
31 окт 18, 01:30    [21719708]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Miracle9
Member

Откуда:
Сообщений: 102
Котовасия
Miracle9,

а по-другому - никак, только после копирования в стриглист?

Ты хоть проверь, доходит ли дело до формирования выходной строки. Может, у тебя все на Format() падает.
Почему не используешь superobject, если такой ленивый. Там и в файл, и в поток сохранение есть, и быдлокодить в два раза меньше.

Пробавал без Format() тоже самое.
Меня обычный JSON устраивал, всё что нужно есть.
А на счёт "быдлокодить", какие в интернете статьи такие и кодеры :)
Спасибо Дмитрию за TJsonTextWriter. Прикольная вещь. Думаю буду теперь её использовать.
31 окт 18, 01:43    [21719712]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Котовасия
Member

Откуда:
Сообщений: 1187
Miracle9,

что ты "без Format" пробовал?
31 окт 18, 03:15    [21719727]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Miracle9
Member

Откуда:
Сообщений: 102
Переделал я код, проблема осталась - out of memory
Если при сохранении файл получается меньше 80мб всё ок, больше ошибка

procedure TFMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
  i, j: integer;
  StringWriter: TStringWriter;
  Writer: TJsonTextWriter;
  SW: TStreamWriter;
begin
  SW := TStreamWriter.Create(ExtractFilePath(Application.ExeName) + 'DATA.json', False, TEncoding.UTF8);
  StringWriter := TStringWriter.Create;
  Writer := TJsonTextWriter.Create(StringWriter);
  try
    Writer.Formatting := TJsonFormatting.Indented;

    Writer.WriteStartObject;
    if (Tools.Count > 0) then
    begin
      Writer.WritePropertyName('Tools');
      Writer.WriteStartArray;
      for i := 0 to Tools.Count - 1 do
      begin
        Writer.WriteStartObject;
        Writer.WritePropertyName('name');
        Writer.WriteValue(Tools[i].name);
        Writer.WritePropertyName('symbol');
        Writer.WriteValue(Tools[i].symbol);
        Writer.WritePropertyName('link');
        Writer.WriteValue(Tools[i].link);
        if (Tools[i].Data.Count > 0) then
        begin
          Writer.WritePropertyName('Data');
          Writer.WriteStartArray;
          for j := 0 to Tools[i].Data.Count - 1 do
          begin
            Writer.WriteStartObject;
            Writer.WritePropertyName('date');
            Writer.WriteValue(DateToStr(Tools[i].Data[j].Date));
            Writer.WritePropertyName('open');
            Writer.WriteValue(Tools[i].Data[j].open);
            Writer.WritePropertyName('high');
            Writer.WriteValue(Tools[i].Data[j].open);
            Writer.WritePropertyName('low');
            Writer.WriteValue(Tools[i].Data[j].low);
            Writer.WritePropertyName('close');
            Writer.WriteValue(Tools[i].Data[j].close);
            Writer.WriteEndObject;
          end;
          Writer.WriteEndArray;
        end;
        Writer.WriteEndObject;
      end;
      Writer.WriteEndArray;
    end;
    Writer.WriteEndObject;

    SW.WriteLine(StringWriter.ToString);
  finally
    FreeAndNil(Writer);
    FreeAndNil(StringWriter);
    FreeAndNil(SW);
  end;
end;
31 окт 18, 16:05    [21720516]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2922
Miracle9,

глянь память, что вообще происходит. возможно что её на самом деле не хватает.
можно порекомендовать библиотеки для замены: SuperObject, XSuperObject.
31 окт 18, 16:18    [21720545]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Dmitry Arefiev
Member

Откуда:
Сообщений: 9647
FS := TFileStream.Create(...);
SW := TStreamWriter.Create(FS);
JTW := TJsonTextWriter.Create(SW);
31 окт 18, 16:38    [21720561]     Ответить | Цитировать Сообщить модератору
 Re: Сохранение JSON объекта  [new]
Miracle9
Member

Откуда:
Сообщений: 102
Dmitry Arefiev
FS := TFileStream.Create(...);
SW := TStreamWriter.Create(FS);
JTW := TJsonTextWriter.Create(SW);

Спасибо Дмитрий, работает!
31 окт 18, 17:09    [21720610]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить