2009-09-30 54 views
2

考虑下面的代码:XmlMtomReader阅读策略

Stream stream = GetStreamFromSomewhere(); 
XmlDictionaryReader mtomReader =XmlDictionaryReader.CreateMtomReader 
(
stream, 
Encoding.UTF8, 
XmlDictionaryReaderQuoatas.Max 
); 

/// ... 

/// is there best way to read binary data from mtomReader's element?? 
string elementString = mtomReader.XmlReader.ReadElementString(); 
byte[] elementBytes = Covert.FromBase64String(elementString); 
Stream elementFileStream = new FileStream(tempFileLocation); 
elementFileStream.Write(elementBytes,0,elementBytes.Length); 
elementFileStream.Close(); 

/// ... 

mtomReader.Close(); 

的问题是,假定二进制附件的大小是100MB之间有时。有没有一种方法可以逐块读取元素的二进制附件,然后将其写入临时文件流,这样我就可以避免为空洞内容分配内存了?

第二个 - 甚至更具体的问题 - mtomReader是否在读取元素的内容之前创建mime二进制附件的内部缓存,即为二进制数据分配内存?还是直接从输入流中读取字节?

回答

3

对于那些谁可能有兴趣的解决方案:

using (Stream stream = GetStreamFromSomewhere()) 
{ 
    using (
    XmlDictionaryReader mtomReader = XmlDictionaryReader.CreateMtomReader(
     stream, Encoding.UTF8, XmlDictionaryReaderQuotas.Max)) 
{ 
    string elementString = mtomReader.ReadElementString(); 
    byte[] buffer = new byte[1024]; 
    using (
     Stream elementFileStream = 
      new FileStream(tempFileLocation, FileMode.Create)) 
    { 
     while(mtomReader.XmlReader.ReadElementContentAsBase64(buffer,0,buffer.Length) 
     { 
      elementFileStream.Write(buffer, 0, buffer.Length); 
     } 
    } 

    /// ... 

    mtomReader.Close(); 
} 
} 

ReadElementContentAsBase64(...)帮助读取二进制部分逐块。我的帖子的第二个问题在这里完美覆盖:Does XmlMtomReader cache binary data from the input stream internally?

0

对于那个大小的附件,最好是使用流式传输。

流传输可以提高 的 可扩展性的服务消除了大 内存缓冲区的要求。是否更改 传输模式可提高可伸缩性 取决于正在传输的消息的大小 。大消息大小 支持使用流式传输。

参见:http://msdn.microsoft.com/en-us/library/ms731913.aspx

+0

谢谢。但那也不代表我的问题。我正在使用XmlMtomReader,而不是WCF服务。 – sh0gged

0

首先,你的代码应该是更多这样的:

using (Stream stream = GetStreamFromSomewhere()) 
{ 
    using (
     XmlDictionaryReader mtomReader = XmlDictionaryReader.CreateMtomReader(
      stream, Encoding.UTF8, XmlDictionaryReaderQuotas.Max)) 
    { 
     string elementString = mtomReader.ReadElementString(); 
     byte[] elementBytes = Convert.FromBase64String(elementString); 
     using (
      Stream elementFileStream = 
       new FileStream(tempFileLocation, FileMode.Create)) 
     { 
      elementFileStream.Write(
       elementBytes, 0, elementBytes.Length); 
     } 

     /// ... 

     mtomReader.Close(); 
    } 
} 

没有using块,你在资源泄漏的风险。

+0

没错。但是这无法解决我的问题。 :( – sh0gged

+0

我希望答案是显而易见的,但事实并非如此,我可能会使用'ReadSubTree'方法读取块中的内容可能会有所帮助,但我不确定 –