2014-01-23 21 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