3

考虑以下代码:

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 二进制附件的任何内部缓存,即为二进制数据分配内存?还是直接从输入流中读取字节?

4

3 回答 3

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(...) 有助于逐块读取二进制部分。我的帖子的第二个问题在这里得到了完美的介绍:XmlMtomReader 是否在内部缓存来自输入流的二进制数据?

于 2009-10-02T08:06:38.517 回答
0

对于这种大小的附件,最好使用流式传输。

流传输可以通过消除对大内存缓冲区的需求来提高服务的可伸缩性。更改传输模式是否会提高可伸缩性取决于正在传输的消息的大小。大消息大小有利于使用流传输。

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

于 2009-09-30T21:21:57.977 回答
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块,您将面临资源泄漏的风险。

于 2009-09-30T22:18:43.230 回答