Проблема с декомпрессией C # - PullRequest
2 голосов
/ 27 апреля 2010

Есть некоторые данные в столбце типа изображения Sybase, которые я хочу использовать в приложении C #. Данные были сжаты Java с использованием пакета java.util.zip. Я хотел проверить, что я могу распаковать данные в C #. Поэтому я написал тестовое приложение, которое извлекает его из базы данных:

byte[] bytes = (byte[])reader.GetValue(0);  

Это дает мне сжатый байт [] длиной 2479.
Затем я передаю это, казалось бы, стандартному методу декомпрессии C #:

public static byte[] Decompress(byte[] gzBuffer)
{
    MemoryStream ms = new MemoryStream();
    int msgLength = BitConverter.ToInt32(gzBuffer, 0);
    ms.Write(gzBuffer, 4, gzBuffer.Length - 4);
    byte[] buffer = new byte[msgLength];

    ms.Position = 0;
    GZipStream zip = new GZipStream(ms, CompressionMode.Decompress);
    zip.Read(buffer, 0, buffer.Length);

    return buffer;
}  

Значение для msgLength равно 1503501432, что, кажется, выходит за пределы допустимого диапазона. Оригинальный документ должен быть в диапазоне 5K-50K. В любом случае, когда я использую это значение для создания «буфера», неудивительно, что я получаю исключение OutOfMemoryException. Что происходит? Jim

Метод сжатия Java выглядит следующим образом:

public byte[] compress(byte[] bytes) throws Exception {
    byte[] results = new byte[bytes.length];
    Deflater deflator = new Deflater();
    deflater.setInput(bytes);
    deflater.finish();
    int len = deflater.deflate(results);
    byte[] out = new byte[len];
    for(int i=0; i<len; i++) {
        out[i] = results[i];
    }
    return(out);
}  

1 Ответ

9 голосов
/ 27 апреля 2010

Поскольку я не вижу ваш код Java, я могу только догадываться, что вы сжимаете свои данные в поток zip-файлов. Поэтому он, очевидно, потерпит неудачу, если вы попытаетесь распаковать этот поток с помощью распаковки gzip в c #. Либо вы изменяете свой Java-код на сжатие gzip (пример здесь внизу страницы), либо вы распаковываете поток zip-файлов в c # с помощью соответствующей библиотеки (например, SharpZipLib ) .

Обновление

Хорошо, теперь я вижу, что вы используете deflate для сжатия в Java. Итак, очевидно, что вы должны использовать тот же алгоритм в C #: System.IO.Compression.DeflateStream

public static byte[] Decompress(byte[] buffer)
{
    using (MemoryStream ms = new MemoryStream(buffer))
    using (Stream zipStream = new DeflateStream(ms, 
                          CompressionMode.Decompress, true))
    {
        int initialBufferLength = buffer.Length * 2;

        byte[] buffer = new byte[initialBufferLength];
        bool finishedExactly = false;
        int read = 0;
        int chunk;

        while (!finishedExactly && 
              (chunk = zipStream.Read(buffer, read, buffer.Length - read)) > 0)
        {
            read += chunk;

            if (read == buffer.Length)
            {
                int nextByte = zipStream.ReadByte();

                // End of Stream?
                if (nextByte == -1)
                {
                    finishedExactly = true;
                }
                else
                {
                    byte[] newBuffer = new byte[buffer.Length * 2];
                    Array.Copy(buffer, newBuffer, buffer.Length);
                    newBuffer[read] = (byte)nextByte;
                    buffer = newBuffer;
                    read++;
                }
            }
        }
        if (!finishedExactly)
        {
            byte[] final = new byte[read];
            Array.Copy(buffer, final, read);
            buffer = final;
        }
    }

    return buffer;
}  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...