directories in a zip file when using java.util.zip.ZipOutputStream

Viewed 87065

Lets say I have a file t.txt, a directory t and another file t/t2.txt. If I use the linux zip utility "zip -r t.zip t.txt t", I get a zip file with the following entries in them (unzip -l t.zip):

Archive:  t.zip
  Length     Date   Time    Name
 --------        ----      ----      ----
        9  04-11-09 09:11   t.txt
        0  04-11-09 09:12   t/
      15  04-11-09 09:12   t/t2.txt
 --------                           -------
       24                          3 files

If I try to replicate that behavior with java.util.zip.ZipOutputStream and create a zip entry for the directory, java throws an exception. It can handle only files. I can create a t/t2.txt entry in the zip file and add use the t2.txt file contents to it but I can't create the directory. Why is that?

6 Answers

ZipOutputStream can handle empty directories by adding a forward-slash / after the folder name. Try (from)

public class Test {
    public static void main(String[] args) {
        try {
            FileOutputStream f = new FileOutputStream("test.zip");
            ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(f));
            zip.putNextEntry(new ZipEntry("xml/"));
            zip.putNextEntry(new ZipEntry("xml/xml"));
            zip.close();
        } catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

You can add "/" at the end of folder name. Just use the following command:

zip.putNextEntry(new ZipEntry("xml/"));

String dir = "E:\Infor\Marketing\JobLog\Cloud_MomBuild_NoMirror";

public void downloadAsZip() throws IOException {
    ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
    ZipOutputStream zipOutputStream = new ZipOutputStream(byteOutputStream);
    Path folderPath = Paths.get(dir);
    String folderName = "Output";
    for (File file : folderPath.toFile().listFiles()) {
        String path = folderName + "/" + file.getName();
        if (file.isDirectory()) {
            writeFolderToZip(zipOutputStream, file, path);
        } else {
            writeFileToZip(zipOutputStream, file, path);
        }
    }
}

public void writeFileToZip(ZipOutputStream zipOutputStream, File file, String path) throws IOException {
    zipOutputStream.putNextEntry(new ZipEntry(path));
    FileInputStream fileInputStream = new FileInputStream(file);
    IOUtils.copy(fileInputStream, zipOutputStream);
    fileInputStream.close();
    zipOutputStream.closeEntry();
}

public void writeFolderToZip(ZipOutputStream zipOutputStream, File dir, String path) throws IOException {
    for (File file : dir.listFiles()) {
        String dirPath = path + "/" + file.getName();
        if (file.isDirectory()) {
            writeFolderToZip(zipOutputStream, file, dirPath);
        } else {
            writeFileToZip(zipOutputStream, file, dirPath);
        }
    }
}
Related