Этот метод застегивает папку и добавляет все дочерние файлы & amp; папки (включая пустые папки) в zip-файл.
void zipFolder(Path sourceDir, Path targetFile) throws IOException {
ZipDirectoryVisitor zipVisitor = new ZipDirectoryVisitor(sourceDir);
Files.walkFileTree(sourceDir, zipVisitor);
FileOutputStream fos = new FileOutputStream(targetFile.toString());
ZipOutputStream zos = new ZipOutputStream(fos);
byte[] buffer = new byte[1024];
for (ZipEntry entry : zipVisitor.getZipEntries()) {
zos.putNextEntry(entry);
Path curFile = Paths.get(sourceDir.getParent().toString(), entry.toString());
if (!curFile.toFile().isDirectory()) {
FileInputStream in = new FileInputStream(Paths.get(sourceDir.getParent().toString(), entry.toString()).toString());
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
}
zos.closeEntry();
}
zos.close();
}
И вот реализация ZipDirectoryVisitor:
class ZipDirectoryVisitor extends SimpleFileVisitor<Path> {
private Path dirToZip;
private List<ZipEntry> zipEntries; // files and folders inside source folder as zip entries
public ZipDirectoryVisitor(Path dirToZip) throws IOException {
this.dirToZip = dirToZip;
zipEntries = new ArrayList<>();
}
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
// According to zip standard backslashes
// should not be used in zip entries
String zipFile = dirToZip.getParent().relativize(path).toString().replace("\\", "/");
ZipEntry entry = new ZipEntry(zipFile);
zipEntries.add(entry);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
String zipDir = dirToZip.getParent().relativize(path).toString().replace("\\", "/");
// Zip directory entries should end with a forward slash
ZipEntry entry = new ZipEntry(zipDir + "/");
zipEntries.add(entry);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path path, IOException e) throws IOException {
System.err.format("Could not visit file %s while creating a file list from file tree", path);
return FileVisitResult.TERMINATE;
}
public List<ZipEntry> getZipEntries() {
return zipEntries;
}
}