> Как реализовать чтение JSON по строкам с использованием потоков (C#)
Уровень: senior · Роль: backend · Язык: C# · Категория: Технические вопросы
Компании: Ozon
Стек: C# /.NET
> Пример ответа
Короткий ответ
Для чтения JSON по строкам в C#/.NET используйте System.Text.Json с JsonSerializer.DeserializeAsyncEnumerable<T> или JsonDocument/Utf8JsonReader в потоковом режиме. Для построчного чтения NDJSON применяйте StreamReader.ReadLineAsync и десериализуйте каждую строку отдельно. Это позволяет обрабатывать большие файлы без загрузки всего содержимого в память, что критично для backend-сервисов с ограниченными ресурсами.
Подробное объяснение
Потоковое чтение JSON бывает двух основных сценариев: NDJSON (newline-delimited JSON), где каждый объект на отдельной строке, и большой единый JSON-массив. В первом случае достаточно StreamReader.ReadLineAsync в цикле с JsonSerializer.Deserialize<T>. Во втором - JsonSerializer.DeserializeAsyncEnumerable<T> из .NET 6+ возвращает IAsyncEnumerable<T>, читая элементы массива по мере поступления. Альтернатива - Utf8JsonReader для ручного парсинга без аллокаций, но он сложнее и требует ручного управления состоянием. Для очень больших файлов комбинируйте FileStream с FileOptions.SequentialScan и буферизацией. Важно учитывать backpressure: IAsyncEnumerable с WithCancellation и ConfigureAwait(false) предотвращает блокировки. На senior-уровне ожидается понимание trade-off между аллокациями, пропускной способностью и сложностью кода.
На практике
В микросервисах часто приходят NDJSON-логи или стриминговые ответы API. Читайте через HttpClient.GetStreamAsync и ReadLineAsync, десериализуя построчно. Для единого массива используйте DeserializeAsyncEnumerable с JsonSerializerOptions и CancellationToken. Не забывайте про JsonSerializerOptions.PropertyNameCaseInsensitive и обработку JsonException для битых строк. При работе с Utf8JsonReader применяйте ReadOnlySequence<byte> и SequenceReader для эффективного парсинга без копирования. В high-load сценариях рассмотрите System.IO.Pipelines для управления буферами.
Пример кода
CSHARP// NDJSON: построчное чтениеawait using var stream = File.OpenRead("data.ndjson");using var reader = new StreamReader(stream);while (!reader.EndOfStream){var line = await reader.ReadLineAsync();if (string.IsNullOrWhiteSpace(line)) continue;var item = JsonSerializer.Deserialize<MyDto>(line);// обработка item}// JSON-массив: потоковая десериализацияawait using var fs = File.OpenRead("array.json");await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<MyDto>(fs)){// обработка item}
Как отвечать на собеседовании
Начните с уточнения формата: NDJSON или единый массив. Затем предложите DeserializeAsyncEnumerable для массива и ReadLineAsync для NDJSON. Упомяните Utf8JsonReader как low-level опцию с минимальными аллокациями. Объясните, почему не стоит использовать JsonDocument.Parse для больших файлов - он загружает всё в память. Добавьте про CancellationToken и ConfigureAwait(false) для асинхронной обработки. Если спросят про производительность, расскажите о System.IO.Pipelines и ArrayPool<byte>.
Что проверяет интервьюер
Понимание потоковой обработки и управления памятью. Знание System.Text.Json и его асинхронных API. Умение выбирать между JsonDocument, Utf8JsonReader и DeserializeAsyncEnumerable. Опыт работы с IAsyncEnumerable и отменой операций. Способность обсуждать trade-off между простотой и производительностью. Навык обработки ошибок и частичных данных в потоке.
Типичные ошибки
Использование JsonDocument.Parse для больших файлов, что приводит к OOM. Игнорирование CancellationToken и ConfigureAwait(false). Чтение всего потока в строку перед парсингом. Отсутствие обработки JsonException для отдельных строк в NDJSON. Забывание про FileOptions.SequentialScan для больших файлов. Синхронные вызовы ReadLine в асинхронном контексте. Неправильная работа с Utf8JsonReader без учёта IsFinalBlock и TokenType.
> Похожие задачи по C#
> Похожие задачи по backend
Какие ошибки могут возникнуть при работе с JSON в Java и как их обработать
Можно ли из класса контроллера в Java вернуть объект, который сериализуется в JSON
Как обрабатывать отсутствие одинаковых строк в JSON
Как пропускать некорректный JSON и продолжать обработку
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью