是否可以使用 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 上,并且可能随后会降低应用程序性能。