Newtonsoft.Json - исключение нехватки памяти при десериализации большого объекта

У меня проблема с десериализацией файла JSON размером около 1 ГБ. Когда я запускаю следующий код, я получаю исключение нехватки памяти:

using (FileStream sr = new FileStream("myFile.json", FileMode.Open, FileAccess.Read))
{
  using (StreamReader reader = new StreamReader(sr))
  {
    using (JsonReader jsReader = new JsonTextReader(reader))
    {
      JsonSerializer serializer = new JsonSerializer();
      dataObject = serializer.Deserialize<T>(jsReader);
    }
  }
}

исключение выбрасывается

Newtonsoft.Json.Linq.JTokenWriter.WriteValue(Int64 value)

Сериализация работает хорошо, вот код, который я использую

using (StreamWriter reader = new StreamWriter("myFile.json"))
{
   using (JsonReader jsWriter = new JsonWriter(reader))
   {
      JsonTextWriter jsonWriter = new JsonTextWriter(jsWriter) { Formatting = Formatting.Indented };
      JsonSerializer ser = new JsonSerializer();
      ser.Serialize(jsonWriter, dataObject, dataObject.GetType());
      jsonWriter.Flush();
    }
}}

Я делаю что-то не так в десериализации? Можете ли вы помочь предложить способ десериализации большого объекта JSON?

Спасибо

2 ответа

Решение

В соответствии с советами по производительности от Newtonsoft.Json ваш подход должен работать (потому что вы читаете через поток, и он должен делать часть из вашего файла). Я не могу понять, почему твой код не работает.

Но вы можете попробовать другой подход, который был описан в следующей статье - Парсинг больших записей с Json.NET

Я знаю, что это старый вопрос, но я только что столкнулся с той же проблемой с 50 ГБjsonфайл. Вот мое решение:

      using (FileStream sr = new FileStream(jsonFile, FileMode.Open, FileAccess.Read))
using (StreamReader fileReader = new StreamReader(sr))
using (JsonTextReader jsonReader = new JsonTextReader(fileReader))
{
    JsonSerializer jsonSerializer = new JsonSerializer();
    List<JObject> documentBatch = new List<JObject>();

    while (jsonReader.Read())
    {
        if (jsonReader.TokenType == JsonToken.StartObject)
        {                   
            JObject document = jsonSerializer.Deserialize<JObject>(jsonReader);             
            documentBatch.Add(document);
            
            if (documentBatch.Count >= 1000) // Adjust the batch size as needed
            {
                foreach (JObject item in documentBatch)
                {
                    //do your stuff
                }
                
                documentBatch.Clear();
            }               
        }
    }
}
Другие вопросы по тегам