OutOfMemoryException с использованием BZip2 (SharpZipLib)

Я использую Asp.net, .net 3.5, win2003, iis 6.0.

Я использую Oracle для сбора файлов, сохранения файла в сжатом формате SharpZipLib.BZip2 в поле RAW в таблице Oracle.

Мое приложение является веб-приложением, и я использую службу WCF для получения данных (массива байтов) файла. Страница aspx отправляет файл пользователю (файл загрузки).

Моя проблема-проблема:

Я читаю ДАННЫЕ из Oracle (звоню в службу WCF). Получаю массив байтов (byte []),

Я пытаюсь распаковать файл с помощью SharpZipLib.BZip2

using (MemoryStream inData = new MemoryStream(data))
{ 
using (MemoryStream outData = new MemoryStream())
{
          BZip2.Decompress(inData, outData); //<==================== Fails here OutOfMemoryException
          return outData.ToArray();
}

}

ошибка из-за того, что файл "несжатый" большой, очень большой (> 500 МБ) !!!

сжатый файл: 4 МБ

несжатый файл:> 500 МБ

Я тестирую вот так:

BufferedStream bufin = new BufferedStream(instream);

            using (MemoryStream outData = new MemoryStream())
            {
                BZip2.Decompress(bufin, outData);

                return outData.ToArray();
            }

Но я получаю то же исключение OutOfMemoryException

Стек исключения трассировки

   en System.IO.MemoryStream.set_Capacity(Int32 value)
   en System.IO.MemoryStream.EnsureCapacity(Int32 value)
   en System.IO.MemoryStream.WriteByte(Byte value)
   en Reale.Frk.Compression.BZip2.BZip2.Decompress(Stream inStream, Stream outStream)

Код SharpZipLib.BZip2.Decompress

public static void Decompress(Stream inStream, Stream outStream) 

            {

                  if ( inStream == null ) {

                        throw new ArgumentNullException("inStream");

                  }

                  if ( outStream == null ) {

                        throw new ArgumentNullException("outStream");

                  }


                  using ( outStream ) {

                        using ( BZip2InputStream bzis = new BZip2InputStream(inStream) ) {

                             int ch = bzis.ReadByte();

                             while (ch != -1) {

                                   outStream.WriteByte((byte)ch);

                                   ch = bzis.ReadByte();

                             }

                        }

                  }

            }

какие-либо предложения, комментарии, образцы исходного кода?


person Kiquenet    schedule 30.07.2010    source источник


Ответы (2)


Пропустите MemoryStream и напишите прямо в файл.

В противном случае добавьте больше памяти на сервер.

Другой вариант указать начальную емкость для MemoryStream.

person leppie    schedule 30.07.2010
comment
Требования приложения, я предпочитаю избегать записи в файл :(. Добавить дополнительную память сервера невозможно. - person Kiquenet; 30.07.2010
comment
Тогда ты облажался. Попробуйте использовать менее интенсивный алгоритм распаковки памяти. Если добавление памяти является проблемой, я подозреваю, что у вас проблемы посерьезнее .... - person leppie; 30.07.2010
comment
любое другое решение, пожалуйста? - person Kiquenet; 30.06.2015
comment
@Kiquenet: используйте потоковое сжатие. GZip уже встроен. - person leppie; 30.06.2015

Скорее всего, вы получаете ошибку нехватки памяти, потому что единственная непрерывная область памяти для потока памяти размером 500 МБ недоступна в вашей системе, но у вас может быть достаточно несмежных блоков памяти. Вместо этого используйте класс MemoryTributary, и это может сработать. Класс может потребовать некоторой настройки (если я правильно помню, он может не вернуть самый последний блок и дополнить его ASCII (0))

person ajeh    schedule 19.04.2017