Domanda

Uso questo codice per creare un .zip con un elenco di file:

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();

Non so come funzionano l'algoritmo zip e ZipOutputStream, se scrive qualcosa prima di leggere e inviare a 'zos' tutti i dati, il file del risultato può essere diverso in dimensioni di byte rispetto a se ne scelgo un altro dimensione buffer.

in altre parole non so se l'algoritmo sia simile:

LEGGI DATI - > PROCESS DATA - > CREATE .ZIP

o

LEGGI CHUNK DI DATI - > PROCESSO CHUNK DI DATI - > SCRIVI CHUNK IN .ZIP - > | ^ ------------------------------------------------- -------------------------------------------------- --------------------------

In questo caso, quale dimensione del buffer è la migliore?

Aggiornamento:

Ho testato questo codice, cambiando la dimensione del buffer da 1024 a 64 e comprimendo gli stessi file: con 1024 byte il file di risultato 80 KB era 3 byte più piccolo rispetto a un buffer di 64 byte. Qual è la dimensione del buffer migliore per produrre il file .zip più piccolo nei periodi più difficili?

È stato utile?

Soluzione

Risposta breve: sceglierei qualcosa come 16k.


Risposta lunga:

ZIP utilizza l'algoritmo DEFLATE per la compressione ( http://en.wikipedia.org/wiki/DEFLATE ). Deflate è un sapore di Ziv Lempel Welch (cerca su Wikipedia per LZW). DEFLATE utilizza la codifica LZ77 e Huffman.

Questa è una compressione del dizionario e, per quanto ne so dal punto di vista dell'algoritmo, la dimensione del buffer utilizzata durante l'immissione dei dati nel deflattore non dovrebbe avere quasi alcun impatto. L'impatto maggiore per LZ77 sono le dimensioni del dizionario e la finestra scorrevole, che non sono controllate dalla dimensione del buffer nel tuo esempio.

Penso che puoi provare diverse dimensioni del buffer se vuoi e tracciare un grafico, ma sono sicuro che non vedrai cambiamenti significativi nel rapporto di compressione (3/80000 = 0,00375%).

L'impatto maggiore della dimensione del buffer è sulla velocità a causa della quantità di codice ambientale che viene eseguito quando si effettuano le chiamate a FileInputStream.read e zos.write. Da questo punto di vista dovresti tenere conto di ciò che guadagni e di ciò che spendi.

Quando si aumenta da 1 byte a 1024 byte, si perdono 1023 byte (in teoria) e si ottiene una riduzione di ~ 1024 del tempo di overhead nei metodi .read e .write. Tuttavia, quando aumenti da 1k a 64k, stai spendendo 63k, riducendo il sovraccarico di 64 volte.

Quindi questo ha rendimenti decrescenti, quindi sceglierei un punto nel mezzo (diciamo 16k) e resterei fedele.

Altri suggerimenti

Dipende dall'hardware che hai (velocità del disco e tempo di ricerca dei file). Direi che se non sei interessato a spremere l'ultimo calo delle prestazioni scegli una dimensione tra 4k e 64k. Poiché è un oggetto di breve durata, verrà comunque raccolto rapidamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top