2013-08-16 35 views
3

我想通過顯式構建文檔來將JSON寫入Stream。例如:將JSON寫入流而不緩衝內存中的字符串

var stream = ...; 
var writer = new JsonWriter(stream); 

writer.BeginArray(); 
{ 
    writer.BeginObject(); 
    { 
    writer.String("foo"); 
    writer.Number(1); 
    writer.String("bar"); 
    writer.Number(2.3); 
    } 
    writer.EndObject(); 
} 
writer.EndArray(); 

這將產生:

[ 
    { 
    "foo": 1, 
    "bar": 2.3 
    } 
] 

這種方法的好處是,沒有什麼需要在內存中緩存。在我的情況下,我寫了很多JSON流。諸如this one之類的解決方案涉及在內存中創建所有對象,然後將它們序列化爲內存中的大字符串,最後將此字符串寫入流並垃圾收集,可能來自LOH。我想保持我的內存使用率低,在從另一個文件/數據庫/數據流中讀取數據時寫出元素。

這種方法在C++中通過rapidjson library提供。

我已經搜索了一些相關信息,但沒有找到解決方案。

回答

9

原來我需要Google多一點時間。

JSON.NET確實通過它的JsonWriter類支持。

我的例子將寫成:

Stream stream = ...; 

using (var streamWriter = new StreamWriter(stream)) 
using (var writer = new JsonTextWriter(streamWriter)) 
{ 
    writer.Formatting = Formatting.Indented; 

    writer.WriteStartArray(); 
    { 
     writer.WriteStartObject(); 
     { 
      writer.WritePropertyName("foo"); 
      writer.WriteValue(1); 
      writer.WritePropertyName("bar"); 
      writer.WriteValue(2.3); 
     } 
     writer.WriteEndObject(); 
    } 
    writer.WriteEndArray(); 
} 
+0

爲什麼要使用那些不必要的'{''}單曲? – I4V

+1

爲什麼我應該手動顯式編寫所有元素,而不是簡單地執行'jsonSerializer.Serialize(jsonTextWriter,obj)'? – I4V

+2

@ I4V - '{}'是爲了便於閱讀而且是可選的。在一個不平凡的例子中,他們真的可以幫助。如果您有許多要編寫的元素遵循簡單的重複格式,那麼手動編寫元素是一個好主意。例如,如果您正在使用來自'SqlDataReader'的100,000個元素將JSON寫入HTTP響應流,則以這種方式編寫可避免發生「OutOfMemoryException」,即使您沒有OOME,您的Web服務器的性能也會更好。所以,這取決於你的情況的要求。 –