OutOfMemoryException с использованием BZip2 (SharpZipLib) - PullRequest
1 голос
/ 30 июля 2010

Я использую 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();

                             }

                        }

                  }

            }

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

Ответы [ 2 ]

2 голосов
/ 30 июля 2010

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

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

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

0 голосов
/ 19 апреля 2017

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

...