Каков размер буфера для создания архива .zip с использованием Java? - PullRequest
7 голосов
/ 14 октября 2008

Я использую этот код для создания ZIP-файла со списком файлов:

ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));

for (int i=0;i<srcFiles.length;i++){
    String fileName=srcFiles[i].getName();
    ZipEntry zipEntry = new ZipEntry(fileName);
    zos.putNextEntry(zipEntry);
    InputStream fis = new FileInputStream(srcFiles[i]);
    int read;
    for(byte[] buffer=new byte[1024];(read=fis.read(buffer))>0;){
        zos.write(buffer,0,read);
    }
    fis.close();
    zos.closeEntry();
}
zos.close();

Я не знаю, как работает алгоритм zip и ZipOutputStream, если он записывает что-то перед тем, как я прочитаю и отправлю «zos» все данные, размер файла результата может отличаться по размеру от байтов, чем если бы я выбрал другой размер буфера.

другими словами, я не знаю, похож ли алгоритм:

ЧТЕНИЕ ДАННЫХ -> ПРОЦЕСС ДАННЫХ -> СОЗДАТЬ .ZIP

или

ЧИТАТЬ ЧАНК ДАННЫХ -> ПРОЦЕСС ЧАНК ДАННЫХ -> ЗАПИСЬ ЧАСОВ В .ZIP -> | ^ ------------------------------------------------- -------------------------------------------------- --------------------------

Если это так, какой размер буфера является лучшим?

Обновление:

Я проверил этот код, изменив размер буфера с 1024 до 64 и заархивировав те же файлы: при 1024 байтах файл результата размером 80 КБ был на 3 байта меньше, чем с буфером на 64 байта. Каков наилучший размер буфера для создания наименьшего .zip в самое лучшее время?

Ответы [ 2 ]

10 голосов
/ 14 октября 2008

Краткий ответ: я бы выбрал что-то вроде 16k.


Длинный ответ:

ZIP использует алгоритм сжатия DEFLATE (http://en.wikipedia.org/wiki/DEFLATE). Deflate - разновидность Ziv Lempel Welch (поиск по Википедии для LZW). DEFLATE использует LZ77 и кодирование Хаффмана.

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

Я думаю, что вы можете поэкспериментировать с буфером другого размера, если хотите, и построить график, но я уверен, что вы не увидите каких-либо существенных изменений в степени сжатия (3/80000 = 0,00375%).

Наибольшее влияние размер буфера оказывает на скорость из-за объема служебного кода, который выполняется при вызовах FileInputStream.read и zos.write. С этой точки зрения вы должны учитывать, что вы получаете и что вы тратите.

При увеличении с 1 байта до 1024 байтов вы теряете 1023 байта (теоретически) и получаете ~ 1024 сокращения затрат времени в методах .read и .write. Однако при увеличении с 1К до 64К вы тратите 63К, что снижает накладные расходы в 64 раза.

Так что это идет с уменьшением отдачи, поэтому я бы выбрал где-то посередине (скажем, 16k) и придерживался этого.

0 голосов
/ 14 октября 2008

Зависит от того, какое у вас оборудование (скорость диска и время поиска файла). Я бы сказал, если вы не заинтересованы в сжатии последней капли производительности, выберите любой размер от 4 до 64 КБ. Так как это недолговечный объект, он все равно будет быстро собран.

...