是否可以使用Json.NET序列化爲NDJSON(Newline Delimited JSON)? Elasticsearch API使用NDJSON進行批量操作,並且我沒有發現任何暗示此格式由.NET庫支持的任何內容。使用Json.NET序列化爲NDJSON
This answer提供指導反序列化NDJSON,並有人指出,一個能夠獨立序列每一行和新行加入,但我不一定會調用支持。
是否可以使用Json.NET序列化爲NDJSON(Newline Delimited JSON)? Elasticsearch API使用NDJSON進行批量操作,並且我沒有發現任何暗示此格式由.NET庫支持的任何內容。使用Json.NET序列化爲NDJSON
This answer提供指導反序列化NDJSON,並有人指出,一個能夠獨立序列每一行和新行加入,但我不一定會調用支持。
最簡單的答案是寫使用的每一行單獨JsonTextWriter
單TextWriter
,設置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);
}
// 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上,並且可能隨後降低應用程序性能。
由於使用了JsonTextWriter而接受答案。看起來這是在圖書館已經提供的內容中最爲理智的方法,並且與其他答案爲每行創建新TextWriter的方法相比,它顯着更具有性能。 –
其實,以上是爲每一行創建一個JsonTextWriter的答案。 – jlavallet
@jlavallet - 'JsonConvert.SerializeObject()'在內部創建一個'StringWriter'和一個'JsonTextWriter';有關詳細信息,請參見[https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/JsonConvert.cs#L647]。由於單個JSON行可能很短,但行數可能很大,所以我建議使用流式傳輸解決方案,以避免按照推薦分配大於85kb的單個字符串[http://www.newtonsoft.com/json] /help/html/Performance.htm#MemoryUsage)。 – dbc
你可以試試這個:
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開箱即用。 這是一個公平的問題,Json.NET是否應該明確支持這種格式。什麼是NDJson的輸入類型,一個對象數組? –
我同意Json.NET是否可以支持這個開箱即用的公平問題。 – jlavallet
至於輸入類型是什麼 - 我想從我很快讀到關於NDJSON格式的內容,這取決於上下文。這將是「一行數據」,應該與其他「數據行」分開處理。你的背景是什麼?數據行可能是一個簡單的對象,只有一些屬性,一個複雜的對象有多個子對象級別,或者只是一個字符串,您必須告訴我每行應該出現什麼內容。 – jlavallet
該鏈接指向域抓取。它只是在幾年前創建的,而像AWS和Azure這樣的提供商使用換行符分隔的JSON好幾年 –