Dans Java est-ce que j'instancie un ZipOutputStream en premier ou le BufferedOutputStream en premier? Exemple:
FileOutputStream dest = new FileOutputStream(file);
ZipOutputStream Zip = new ZipOutputStream(new BufferedOutputStream(dest));
// use Zip output stream to write to
Ou:
FileOutputStream dest = new FileOutputStream(file);
BufferedOutputStream out = new BufferedOutputStream(new ZipOutputStream(dest));
// use buffered stream to write to
Dans mes chronologies non scientifiques, je ne peux pas sembler dire beaucoup de différence ici. Je ne vois rien dans l'API Java qui indique si l'une ou l'autre de ces méthodes est nécessaire ou préférable. Tout conseil? Il semble que compresser la sortie en premier, puis la mettre en mémoire tampon pour les écritures serait plus efficace.
Vous devriez toujours envelopper le BufferedOutputStream
avec le ZipOutputStream
, jamais l'inverse. Voir le code ci-dessous:
FileOutputStream fos = new FileOutputStream("hello-world.Zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream zos = new ZipOutputStream(bos);
try {
for (int i = 0; i < 10; i++) {
// not available on BufferedOutputStream
zos.putNextEntry(new ZipEntry("hello-world." + i + ".txt"));
zos.write("Hello World!".getBytes());
// not available on BufferedOutputStream
zos.closeEntry();
}
}
finally {
zos.close();
}
Comme le disent les commentaires, les méthodes putNextEntry()
et closeEntry()
ne sont pas disponibles sur BufferedOutputStream
. Sans appeler ces méthodes, ZipOutputStream
lève une exception Java.util.Zip.ZipException: no current Zip entry
.
Par souci d'exhaustivité, il est à noter que la clause finally appelle uniquement close()
sur le ZipOutputStream
. Ceci est dû au fait que, par convention, toutes les implémentations intégrées du wrapper du flux de sortie Java) propagent la fermeture.
Je viens de tester l'inverse. Il s'avère que le fait d'encapsuler un ZipOutputStream
avec BufferedOutputStream
et de n'appeler que write()
dessus (sans créer/fermer d'entrées) ne jettera pas un ZipException
. Au lieu de cela, le fichier Zip résultant sera corrompu, sans aucune entrée à l'intérieur.
Vous devriez:
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
parce que vous voulez mettre en tampon l'écriture sur le disque (parce que cela est beaucoup plus efficace dans les blocs de données volumineux que dans beaucoup de petits).
Cette
new BufferedOutputStream(new ZipOutputStream(dest));
serait tampon avant la compression Zip. Mais tout cela se passe dans la mémoire et n’a pas besoin de tampon car beaucoup de petits accès mémoire ont à peu près la même vitesse que quelques gros. En mémoire, le temps nécessaire est proportionnel au nombre d'octets en lecture/écriture.
Comme mentionné dans les commentaires:
Les méthodes de ZipOutputStream
qui ne font pas partie de BufferedOutputStream
ne seraient pas disponibles également. Par exemple. putNextEntry
et closeEntry
.