Java - Использование Deflater для записи в файл GZIP - PullRequest
1 голос
/ 26 октября 2011

У меня проблемы с использованием Deflater для записи файла GZIP.Я создал заголовок по умолчанию и использовал CRC32 для отслеживания контрольной суммы.

Файл, который я архивирую, меньше моего буфера, но вывод, который я получаю для этого компрессора, на ~ 200 байт больше, чем должен быть (gzip создает файл в 457 байт, а мой код создает файл из652 байта. Я напечатал сжатый размер, и он говорит, что это было 634 байта) Я сделал hexdump для моего окончательного файла, и он говорит, что и мой трейлер, и мой основной файл неверны, но мой заголовок правильный.Мне не разрешено использовать GZIPOutputStream для этого назначения, но я использовал его код для написания заголовка и трейлера.Количество прочитанных байтов правильное.

Объект «управление» - это объект, который выполняет чтение и запись из System.in и System.out в синхронном режиме (это для многопоточности), и япроверил, что они должны прочитать и записать файл по порядку.Я посмотрел на источник GZIPOutputStream и источник DeflaterOutputStream, и мой код выглядит аналогично, поэтому я не уверен, почему мой компрессор дает мне такой большой сжатый байтовый массив.Я играл с уровнями Deflater и стратегиями, но они дают мне один и тот же результат.

EDIT: конструктор для моего Deflater - это компрессор Deflater = новый Deflater (Deflater.DEFAULT_LEVEL, true);

CRC32 checksum = new CRC32();
                    checksum.reset();
                    int uncompressedLength = 0;

                    uncompressedLength = manage.read(buff, threadNum, prime);

                    if (uncompressedLength > 0)
                    {
                        checksum.update(buff, 0, uncompressedLength);
                        compressor.setInput(buff);
                        compressor.finish();                        
                         byte[] output = new byte[BUFFER_SIZE];
                        compressor.deflate(output);
                        int compressedDataLength = (int) compressor.getBytesWritten();


                        manage.write(output, compressedDataLength, threadNum, (int) checksum.getValue(), uncompressedLength);

1 Ответ

1 голос
/ 27 октября 2011

Класс Deflater имеет три конструктора. В одном с двумя аргументами используется логическое значение, которое, если оно истинно, указывает на то, что поля заголовка ZLIB и контрольная сумма не должны использоваться, а это то, что нужно GZIP. Два других конструктора (один без аргументов, другой только задает уровень сжатия) по умолчанию используют эти поля заголовка и контрольной суммы. Другими словами, это как конструктор с двумя аргументами и false. Может быть, попробуйте тот с логическим значением и установите его в true?

Вот документ конструктора.

...