Comment compresser un répertoire dans un fichier zip ?
Lire le contenu d’un répertoire
Un répertoire, comme un fichier, est représenté par une instance de java.io.File
.
On peut parcourir l’ensemble de ses fichiers avec la méthode listFiles()
, en excluant les répertoires.
File directory = new File(...);
File[] allFiles = directory.listFiles(File::isFile);
for (File file : allFiles) {
//...
}
Pour lire le contenu d’un fichier, on utilise un FileInputStream
, puis on lit chaque byte par byte ou, pour optimiser, par paquets de bytes.
FileInputStream inputStream = new FileInputStream(file);
int data;
while ((data = inputStream.read()) >= 0) {
//...
}
Ecrire un fichier Zip
Pour écrire un fichier Zip, il faut assembler un FileOutputStream
à un ZipOutputStream
.
File zipFile = new File(directory.getName() + ".zip");
FileOutputStream fOut = new FileOutputStream(zipFile);
ZipOutputStream zOut = new ZipOutputStream(fOut);
Pour chaque fichier, on doit créer une entrée du fichier zip, avant d’écrire des bytes, puis de fermer l’entrée.
// Déclaration de la première entrée de l'archive
zOut.putNextEntry(new ZipEntry(file.getName()));
int data;
while ((data = inputStream.read()) >= 0) {
zOut.write(data);
}
zOut.closeEntry();
Exemple complet
Si on assemble tout ces éléments, on peut faire fonctionner cet exemple, pour un répertoire à 1 seul niveau de profondeur.
package fr.sewatech.formation.io;
import java.io.*;
import java.util.zip.*;
public class ZipDirExample {
public static void main(String[] args) throws IOException {
System.out.println(writeZip(new File("nio")));
}
public static File writeZip(File directory) throws IOException {
// Si ce n'est pas un répertoire...
File[] allFiles = directory.listFiles(File::isFile);
if (!directory.isDirectory() || allFiles == null) {
return null;
}
File zipFile = new File(directory.getName() + ".zip");
try (ZipOutputStream zOut
= new ZipOutputStream(new FileOutputStream(zipFile))) {
for (File file : allFiles) {
// Flux de lecture du fichier
FileInputStream inputStream = new FileInputStream(file);
// Déclaration de la première entrée de l'archive
zOut.putNextEntry(new ZipEntry(file.getName()));
int data;
while ((data = inputStream.read()) >= 0) {
zOut.write(data);
}
zOut.closeEntry();
}
return zipFile;
}
}
}
Conclusion
Avec un peu de récursivité, on peut traiter le cas d’un répertoire contenant d’autres répertoires…