2016-04-12 23 views
0

當試圖從MemoryStream(由XmlWriter寫入)讀取時,它會拋出ObjectDisposedException ("Cannot access a closed Stream.")序列化到流然後從流中讀取

我偶然發現,在'using'語句中間關閉XmlWriter允許代碼在不拋出的情況下返回。這裏有點魚腥味。

public static string SerializeToString(T obj) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(T)); 

     using (var stream = new MemoryStream()) 
     using (var writer = XmlWriter.Create(stream)) 
     { 
      serializer.Serialize(writer, obj); 

      writer.Flush(); 
      // Swapping the flush for close fixes the ObjectDisposedException 
      //writer.Close(); 
      stream.Position = 0; 


      using (var reader = new StreamReader(stream)) 
      { 
       return reader.ReadToEnd(); 
      } 
     } 
    } 

這發生在Silverlight和.NET 4.5中。

閱讀各地後,我可以從存儲器中讀取數據流直接將字符串按喬恩的答案herereturn Encoding.UTF8.GetString(stream.GetBuffer(), 0, stream.Length);

但首先我想明白髮生了什麼引起的示例代碼除外。

回答

-1

,示例代碼表現出的問題是雙重配置之(所述的StreamReader和二者的XmlWriter處置他們BaseStream [MemoryStream的])。

將StreamReader放入使用的頂部塊可解決此問題。

但最後我沒必要的StreamReader來獲取文本並用以下去:

 public static string SerializeToString(T obj) 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(T)); 

      using (var memoryStream = new MemoryStream()) 
      using (var writer = XmlWriter.Create(memoryStream)) 
      { 
       serializer.Serialize(writer, obj); 
       return Encoding.UTF8.GetString(memoryStream.GetBuffer(), 0, (int)memoryStream.Length); 
      } 
     } 
+1

非常不好的建議 - 不要關注 - 總是處理'IDisposable'對象。你可以在配置好的'MemoryStream'上使用'MemoryStream.GetBuffer'和'MemoryStream.ToArray',因爲它們的存在正是出於這個原因。 –

+0

你可以請你發佈你的解決方案嗎? 當使用兩個嵌套用途時,兩次處理基本流會發生異常。 我回答我的問題的唯一原因是在原代碼片段中使用嵌套'using'語句時,試圖闡明導致問題的原因。 – aitee

+0

代碼已更新。即使在處置XmlWriter時也是如此。 MemoryStream不能在已經關閉的流上調用dispose時拋出。 如果您有一個更好或更正確的解決方案,我會很感激,如果你會繼續併發布它。 謝謝! – aitee

1

關閉writer也將Close()底層流對象。

您不需要明確關閉寫入器,因爲using語句會在該塊的末尾自動完成。

using (var stream = new MemoryStream()) 
using (var writer = XmlWriter.Create(stream)) 
{  
    ... 
    //writer.Close(); <=== don't do this 
    ... 
} // <=== stream and writer get closed here 
+0

我理解這一點。但沒有關閉reader.ReadToEnd()拋出。 這就是這個問題。 – aitee