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 を超える場合があることです。要素のバイナリ添付ファイルをブロックごとに読み取り、それを一時ファイル ストリームに書き込む方法はありますか?

2 番目の - さらに具体的な問題 - 要素のコンテンツを読み取る前に、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(...) は、ブロック単位でバイナリ パーツを読み取るのに役立ちます。私の投稿の 2 番目の問題は、ここで完全にカバーされています: Does XmlMtomReader cache binary data from input stream internal?

于 2009-10-02T08:06:38.517 に答える
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 に答える
0

そのサイズの添付ファイルの場合は、ストリーミングを使用することをお勧めします。

ストリーミング転送により、大容量のメモリ バッファーが不要になるため、サービスのスケーラビリティが向上します。転送モードを変更することでスケーラビリティが向上するかどうかは、転送されるメッセージのサイズによって異なります。メッセージ サイズが大きい場合は、ストリーミング転送を使用することをお勧めします。

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

于 2009-09-30T21:21:57.977 に答える