是否可以使用 Json.NET 序列化为 NDJSON(换行符分隔的 JSON)? Elasticsearch API 使用 NDJSON 进行批量操作,我找不到任何迹象表明任何 .NET 库都支持这种格式。

This answer 提供了反序列化 NDJSON 的指导,有人指出可以独立序列化每一行并加入换行符,但我不一定会称之为支持。

最佳答案

由于 Json.NET 目前没有将集合序列化为 NDJSON 的内置方法,最简单的答案是使用单独的 TextWriter 为每一行写入单个 JsonTextWriter,为每行设置 CloseOutput = false :

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

示例 fiddle

由于单个 NDJSON 行可能很短,但行数可能很大,因此此答案建议使用流式解决方案,以避免分配大于 85kb 的单个字符串的必要性。正如 Newtonsoft Json.NET Performance Tips 中所解释的,这样的大字符串最终会出现在 large object heap 上,并且可能随后会降低应用程序性能。

10-04 21:01