2014-02-06 6 views
0

Я сжимаю файлы более 2 ГБ на Java, используя последовательное применение двух алгоритмов сжатия; один основанный на LZ и один основанный на Хаффмане. (Это похоже на DEFLATE).Сжатие больших файлов с использованием блоков в Java

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

Альтернативой является сжатие файла в блоках размером 8 МБ (размер, в котором я не получаю ошибку Out-Of-Memory), но тогда у меня есть невозможность в полной мере использовать избыточность во всем файле.

Любые идеи, как выполнять эти операции аккуратно. Нет временных файлов и без сжатия в блоках? Сжимают ли другие инструменты сжатия в блоках? Как они справляются с этой проблемой? С уважением

+0

Если вы используете 64-битную JVM, вы можете выделить достаточно места для кучи, чтобы использовать МНОГО БОЛЬШИХ блоков (то есть 1 ГБ вместо 8 МБ). Посмотрите варианты JVM '-Xms' и' -Xmx'. –

+1

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

+1

Я думаю, что вы переоцениваете «способность полностью использовать избыточность во всем файле». Используйте меньшие блоки. Хотя странно, что вы не можете использовать блок размером более 8 МБ. Кажется, у вас очень маленькая куча. – Holger

ответ

0

Что случилось с трубопроводом потоков? Вы можете читать от InputStream, сжать байты и записать их в выходной поток, который подключен к входному потоку следующего алгоритма. Посмотрите на PipeInputStream и PipeOutputStream.

Я надеюсь, что эти алгоритмы могут работать постепенно.

+0

Привет, спасибо за ваш ответ. Я не понимаю ваше использование слова постепенно. Мой первый алгоритм должен завершиться до того, как будет применен второй. С уважением. –

+0

Я имею в виду, что я надеюсь, что ваш алгоритм может прочитать ограниченный кусок байтов, скопировать их, записать их в выходной поток, чтобы перейти к обработке следующего фрагмента и не хранить в памяти весь вход для его обработки с самого начала до конца. – AlexR

+0

«Мой первый алгоритм должен завершиться до того, как будет применен второй.» кажется довольно странным. Ваш второй алгоритм работает на выходе первого алгоритма назад? –

1

Java поставляется с библиотекой “java.util.zip” для выполнения сжатия данных в формате ZIp. Общая концепция довольно проста.

Библиотека читает файл с помощью «FileInputStream». и добавить имя файла «ZipEntry» и вывести его на «ZipOutputStream»

импорт java.util.zip.ZipEntry и импорт java.util.zip.ZipOutputStream используются для импорта папки Zip в программу.

But how can decompress a file 

?

+0

Этот java.util.zip сжимает и объединяет файлы по отдельности, тогда как я хочу использовать парадигму сплошной компрессии http://en.wikipedia.org/wiki/Solid_compression. java.util.zip также терпит неудачу в больших файлах (2 ГБ +). –

0

Вы можете использовать два уровня: java.util.zip. Во-первых, просто соедините все файлы (без сжатия). Если возможно, сортируйте записи по типу файла, чтобы аналогичные файлы находились рядом друг с другом (это увеличит коэффициент сжатия). Во-вторых, сжимайте этот поток. Вам не нужно запускать две отдельные фазы; вместо этого вы можете перенести первую часть на второй этап, например CompressStream(ConcatenateFiles(directory)). Таким образом, у вас есть zip-файл в другом zip-файле: внешний zip-файл сжимается, внутреннее - нет и содержит все фактические файлы.

Это правда, что у java.util.zip были проблемы с файлами размером более 2 ГБ (я столкнулся с этими проблемами). Тем не менее, я считаю, что это было только для ZipFile, а не для ZipIn/OutputStream. Кроме того, я думаю, что эти проблемы исправлены с недавними версиями Java.

Размер буфера: обычные алгоритмы сжатия, такие как Deflate, не будут обладать размерами блоков больше, чем около 64 КБ. Более сложные алгоритмы могут выиграть от использования больших размеров блоков, например bzip2 up to 900 KB, или LZMA2 up to 2 MB. Все, что выше этого, скорее всего, является доменом data deduplication, что может или не имеет смысла для того, что вы хотите сделать.

 Смежные вопросы

  • Нет связанных вопросов^_^