Java offre alcune utilità che consentono di comprimere un
file in formato ZIP. Queste utilità sono rese disponibili
nel package java.util.zip. Per zippare una cartella, è
necessario scandire i suoi file e aggiungerli al flusso zip che
stiamo costruendo. Ad esempio, supponiamo di avere una cartella
dirPath che vogliamo zippare in un file chiamato
zipFileName:
per semplicità la cartella contiene solo files e non altre
cartelle (se contenesse altre cartelle potremmo zipparle
ricorsivamente). Il codice seguente mostra come è possibile
zippare tale cartella:
public class ZipDir {
public static void zipDirectory(File
dirPath, String zipFileName)
throws IOException {
if(dirPath.exists())
{
ZipOutputStream zos = new ZipOutputStream(
new FileOutputStream(zipFileName));
zip(dirPath, zos);
zos.close();
}
}
private static final void zip(File dirPath,
ZipOutputStream zos)
throws IOException {
File[]
files = dirPath.listFiles();
byte[]
buffer = new byte[8192];
int
read = 0;
for (int
i = 0 ; i < files.length; i++) {
FileInputStream in = new FileInputStream(files[i]);
ZipEntry entry = new ZipEntry(files[i].getPath().substring
(dirPath.getPath().length() + 1));
zos.putNextEntry(entry);
while (-1 != (read = in.read(buffer))) {
zos.write(buffer, 0, read);
}
in.close();
}
}
}
Il punto d’ingresso è il metodo zipDirectory, che prende in input il java.io.File della cartella e il nome del file zip risultato. Il metodo zip si occupa di scandire tutti i files contenuti nella cartella, aggiungendoli allo ZipOutputStream come ZipEntry.
Vediamo invece il codice (leggermente pi`u complesso) che consente di comprimere una directory con tutte le sue sotto-directories e files:
public void zipDir(File directory, File zipfile) throws IOException {
URI base = directory.toURI();
Deque<File> queue = new LinkedList<File>();
queue.push(directory);
OutputStream out = new FileOutputStream(zipfile);
Closeable res = out;
try {
ZipOutputStream zout = new ZipOutputStream(out);
res = zout;
while (!queue.isEmpty()) {
directory = queue.pop();
for (File kid : directory.listFiles()) {
String name = base.relativize(kid.toURI()).getPath();
if (kid.isDirectory()) {
queue.push(kid);
name = name.endsWith("/") ? name : name + "/";
zout.putNextEntry(new ZipEntry(name));
} else {
zout.putNextEntry(new ZipEntry(name));
copy(kid, zout);
zout.closeEntry();
}
}
}
} finally {
res.close();
}
}
private void copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
while (true) {
int readCount = in.read(buffer);
if (readCount < 0) {
break;
}
out.write(buffer, 0, readCount);
}
}
private void copy(File file, OutputStream out) throws IOException {
InputStream in = new FileInputStream(file);
try {
copy(in, out);
} finally {
in.close();
}
}