2014-01-23 69 views
0

我正在嘗試使用WCF DataContractSerializer將DataContract對象序列化到memoryStream中。帶MemoryStream的DataContractSerializer丟失字節

然後我使用memoryStream.ToArray獲取序列化的內容。

最後,我使用另一個fileStream將memoryStream保存到一個文件中。

我最初的工具是這樣的。我在持久化文件的末尾丟失了字節。

public virtual string SerializeTransient(DataObject data, string targetPath) 
    { 
     string securityCode; 

     using (var memoryStream = new MemoryStream()) 
     { 
      using (var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings {Indent = true})) 
      { 
       _serializer.WriteObject(xmlWriter, data); 

       using (var fileStream = new FileStream(targetPath, FileMode.Create)) 
       { 
        securityCode = CalculateSecurityCode(memoryStream.ToArray()); 
        memoryStream.WriteTo(fileStream); 
       } 
      } 
     } 

     return securityCode; 
    } 

如果我使用{}塊移動持久邏輯(見下文),輸出是正確的。它幾乎感覺像WriteObject函數沒有完成它正在做的事情。有人可以向我解釋發生了什麼嗎?謝謝。

public virtual string SerializeTransient(DataObject data, string targetPath) 
    { 
     string securityCode; 

     using (var memoryStream = new MemoryStream()) 
     { 
      using (var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings {Indent = true})) 
      { 
       _serializer.WriteObject(xmlWriter, data); 
      } 

      using (var fileStream = new FileStream(targetPath, FileMode.Create)) 
      { 
       securityCode = CalculateSecurityCode(memoryStream.ToArray()); 
       memoryStream.WriteTo(fileStream); 
      } 
     } 

     return securityCode; 
    } 

回答

2

XmlWriter有一個內部緩衝區。您應該關閉/處置XmlWriter或調用XmlWriter.Flush()以強制所有內容寫入基礎流(memoryStream)。

如果在writer.Flush()之前調用memoryStream.ToArray(),則某些字節可能會保留在內部寫入器緩衝區中。

+0

我明白了。這就是爲什麼在XMLWriter上調用Dispose()有所作爲的原因。謝謝回覆。所以當你寫入XMLWriter時,你實際上在寫內部緩衝區?當明確調用Close()或Dispose()或Flush()時,內部緩衝區會閃現到基礎流? –

+0

是的,實際的寫鏈是XmlWriter - > XmlWriter內部StreamWriter - > MemoryStream。內部StreamWriter具有char [1024]緩衝區,因此內容以char [1024]塊的形式寫入內存流。如果您的內容長度爲1030個字符,則最後6個字符將保留在緩衝區中,直到您調用Flush或Close/Dispose writer。 – PashaPash