Serialize as NDJSON using Json.NET

前端 未结 2 1250
轮回少年
轮回少年 2020-11-29 11:22

Is it possible to serialize to NDJSON (Newline Delimited JSON) using Json.NET? The Elasticsearch API uses NDJSON for bulk operations, and I can find nothing suggesting that

2条回答
  •  时光说笑
    2020-11-29 12:20

    As Json.NET does not currently have a built-in method to serialize a collection to NDJSON, the simplest answer would be to write to a single TextWriter using a separate JsonTextWriter for each line, setting CloseOutput = false for each:

    public static partial class JsonExtensions
    {
        public static void ToNewlineDelimitedJson(Stream stream, IEnumerable 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(TextWriter textWriter, IEnumerable 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");
            }
        }
    }
    

    Sample fiddle.

    Since the individual NDJSON lines are likely to be short but the number of lines might be large, this answer suggests a streaming solution to avoid the necessity of allocating a single string larger than 85kb. As explained in Newtonsoft Json.NET Performance Tips, such large strings end up on the large object heap and may subsequently degrade application performance.

提交回复
热议问题