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();
}
}
}
}