Serializar como NDJSON usando Json.NET

Serializar como NDJSON usando Json.NET

Como Json.NET actualmente no tiene un método incorporado para serializar una colección en NDJSON, la respuesta más simple sería escribir en un solo TextWriter usando un JsonTextWriter separado para cada línea, configurando CloseOutput = false para cada uno:

public static partial class JsonExtensions
{
    public static void ToNewlineDelimitedJson<T>(Stream stream, IEnumerable<T> items)
    {
        // Let caller dispose the underlying stream 
        using (var textWriter = new StreamWriter(stream, new UTF8Encoding(false, true), 1024, true))
        {
            ToNewlineDelimitedJson(textWriter, items);
        }
    }

    public static void ToNewlineDelimitedJson<T>(TextWriter textWriter, IEnumerable<T> items)
    {
        var serializer = JsonSerializer.CreateDefault();

        foreach (var item in items)
        {
            // Formatting.None is the default; I set it here for clarity.
            using (var writer = new JsonTextWriter(textWriter) { Formatting = Formatting.None, CloseOutput = false })
            {
                serializer.Serialize(writer, item);
            }
            // https://web.archive.org/web/20180513150745/http://specs.okfnlabs.org/ndjson/
            // Each JSON text MUST conform to the [RFC7159] standard and MUST be written to the stream followed by the newline character \n (0x0A). 
            // The newline charater MAY be preceeded by a carriage return \r (0x0D). The JSON texts MUST NOT contain newlines or carriage returns.
            textWriter.Write("\n");
        }
    }
}

Ejemplo de violín.

Dado que es probable que las líneas individuales de NDJSON sean cortas, pero la cantidad de líneas puede ser grande, esta respuesta sugiere una solución de transmisión para evitar la necesidad de asignar una sola cadena de más de 85 kb. Como se explica en Sugerencias de rendimiento de Newtonsoft Json.NET , cadenas tan grandes terminan en el montón de objetos grandes y, posteriormente, pueden degradar el rendimiento de la aplicación.