使用 Json.NET 序列化为 NDJSON
Serialize as NDJSON using Json.NET
是否可以使用 Json.NET 序列化为 NDJSON(换行符分隔 JSON)? Elasticsearch API 使用 NDJSON 进行批量操作,我找不到任何迹象表明 any .NET 库支持这种格式。
提供了反序列化 NDJSON 的指导,并指出可以独立序列化每一行并加入换行符,但我不一定会称其为 支持.
你可以试试这个:
string ndJson = JsonConvert.SerializeObject(value, Formatting.Indented);
但现在我发现您不只是希望序列化的对象被漂亮地打印出来。如果你序列化的对象是某种集合或枚举,你能不能自己序列化每个元素?
StringBuilder sb = new StringBuilder();
foreach (var element in collection)
{
sb.AppendLine(JsonConvert.SerializeObject(element, Formatting.None));
}
// use the NDJSON output
Console.WriteLine(sb.ToString());
由于 Json.NET 目前没有将集合序列化为 NDJSON 的内置方法,最简单的答案是使用单独的 JsonTextWriter
for each line, setting CloseOutput = false
写入单个 TextWriter
每个:
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, such large strings end up on the large object heap 中所述,随后可能会降低应用程序性能。
是否可以使用 Json.NET 序列化为 NDJSON(换行符分隔 JSON)? Elasticsearch API 使用 NDJSON 进行批量操作,我找不到任何迹象表明 any .NET 库支持这种格式。
你可以试试这个:
string ndJson = JsonConvert.SerializeObject(value, Formatting.Indented);
但现在我发现您不只是希望序列化的对象被漂亮地打印出来。如果你序列化的对象是某种集合或枚举,你能不能自己序列化每个元素?
StringBuilder sb = new StringBuilder();
foreach (var element in collection)
{
sb.AppendLine(JsonConvert.SerializeObject(element, Formatting.None));
}
// use the NDJSON output
Console.WriteLine(sb.ToString());
由于 Json.NET 目前没有将集合序列化为 NDJSON 的内置方法,最简单的答案是使用单独的 JsonTextWriter
for each line, setting CloseOutput = false
写入单个 TextWriter
每个:
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, such large strings end up on the large object heap 中所述,随后可能会降低应用程序性能。