Чтение больших JSON-файлов
Все мы привыкли читать JSON как-то так (с использованием Json.NET):
Product deserializedProduct = JsonConvert.DeserializeObject(json);
И это отлично работает, пока размер сообщения, которое мы читаем сравнительно небольшой. Вчера мне понадобилось прочить JSON размером 1.7 Гб. Все попытки десериализации сохраненного в файле массива ожидаемо закончились OutOfMemoryException.
Без лишних разговоров, публикую рецепт:
В каждой итерации цикла в переменной obj мы будем получать следующий элемент массива.
Память такой подход не использует вообще :)
Product deserializedProduct = JsonConvert.DeserializeObject
И это отлично работает, пока размер сообщения, которое мы читаем сравнительно небольшой. Вчера мне понадобилось прочить JSON размером 1.7 Гб. Все попытки десериализации сохраненного в файле массива ожидаемо закончились OutOfMemoryException.
Без лишних разговоров, публикую рецепт:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
using System; | |
using System.Diagnostics; | |
using System.IO; | |
namespace ParseJSON { | |
class Program { | |
static void Main(string[] args) { | |
using (var reader = new JsonTextReader(new StreamReader(@"D:\large.json"))) { | |
var result = reader.Read(); | |
if (reader.TokenType != JsonToken.StartArray) | |
throw new ApplicationException("Incorrect file format"); | |
else | |
result = reader.Read(); | |
while (result && reader.TokenType == JsonToken.StartObject) { | |
JToken obj = JObject.ReadFrom(reader); | |
result = reader.Read(); | |
} | |
} | |
} | |
} | |
} |
В каждой итерации цикла в переменной obj мы будем получать следующий элемент массива.
Память такой подход не использует вообще :)
Коментарі
но это ж только "большой массив простых объектов", и при условии, что сами по-себе CS-объекты влезут в память (ок, 1.7G памяти всегда есть).
но сама идея "поточной обработки наборов данных мне кажется очень правильной!