Стратегия чтения XmlMtomReader - PullRequest
       14

Стратегия чтения XmlMtomReader

2 голосов
/ 30 сентября 2009

Рассмотрим следующий код:

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();

Проблема в том, что размер двоичного вложения иногда превышает 100 МБ. Есть ли способ прочитать двоичный блок прикрепления элемента за блоком, а затем записать его во временный файловый поток, чтобы я мог уйти от выделения памяти для дырки?

Второй - еще более специфический вопрос - создает ли mtomReader какой-либо внутренний кэш двоичного вложения mime до того, как я прочитал содержимое элемента, т.е. выделил ли память для двоичных данных? Или он читает байты из входного потока напрямую?

Ответы [ 3 ]

3 голосов
/ 02 октября 2009

Для тех, кого может заинтересовать решение:

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 двоичные данные из входного потока внутренне?

0 голосов
/ 01 октября 2009

Для начала ваш код должен выглядеть примерно так:

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 голосов
/ 01 октября 2009

Для вложений такого размера было бы лучше использовать потоковую передачу.

Потоковые передачи могут улучшить масштабируемость услуги устраняя требование для больших буферы памяти. Будь изменяешь режим передачи улучшает масштабируемость зависит от размера сообщений переводится. Большие размеры сообщений пользу от потоковых переводов.

См .: http://msdn.microsoft.com/en-us/library/ms731913.aspx

...