80

Suppose I have the following directory structure.

D:\reports\january\

Inside january there are suppose two excel files say A.xls and B.xls. There are many places where it has been written about how to zip files using java.util.zip. But I want to zip the january folder itself inside reports folder so that both january and january.zip will be present inside reports. (That means when I unzip the january.zip file I should get the january folder).

Can anyone please provide me the code to do this using java.util.zip. Please let me know whether this can be more easily done by using other libraries.

Thanks a lot...

mukund
  • 2,866
  • 5
  • 31
  • 41
  • 7
    Why moderators don't close this kind of questions, it directly against rules from the first page "Don't ask about... Questions you haven't tried to find an answer for (show your work!)". – CheatEx Jul 08 '14 at 13:54

16 Answers16

110

Have you tried Zeroturnaround Zip library? It's really neat! Zip a folder is just a one liner:

ZipUtil.pack(new File("D:\\reports\\january\\"), new File("D:\\reports\\january.zip"));

(thanks to Oleg Šelajev for the example)

Community
  • 1
  • 1
Petro Semeniuk
  • 6,970
  • 10
  • 42
  • 65
100

Here is the Java 8+ example:

public static void pack(String sourceDirPath, String zipFilePath) throws IOException {
    Path p = Files.createFile(Paths.get(zipFilePath));
    try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p))) {
        Path pp = Paths.get(sourceDirPath);
        Files.walk(pp)
          .filter(path -> !Files.isDirectory(path))
          .forEach(path -> {
              ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
              try {
                  zs.putNextEntry(zipEntry);
                  Files.copy(path, zs);
                  zs.closeEntry();
            } catch (IOException e) {
                System.err.println(e);
            }
          });
    }
}
Halvor Holsten Strand
  • 19,829
  • 17
  • 83
  • 99
Nikita Koksharov
  • 10,283
  • 1
  • 62
  • 71
  • 2
    Small improvements: Put the ZipOutpuStream in try (...) { }; For sp, I've added .replace("\\", "/"); replace sp + "/" + path... by sp + path... – Anthony Mar 20 '16 at 14:11
  • 3
    Obtaining the relative path for the ZipEntry can be simplified to `new ZipEntry(pp.relativize(path).toString())` – simon04 Aug 04 '16 at 08:34
  • 4
    If a file size is big, wouldn't Files.readAllBytes() cause memory bloat? – Keshav Jun 19 '17 at 04:35
  • 1
    @Keshav you're right, can you suggest any solution? – Nikita Koksharov Jun 19 '17 at 13:13
  • @NikitaKoksharov I rewrote the code in the following way to stream the bytes instead of reading them at once into memory: `ZipEntry zipEntry = new ZipEntry(pp.relativize(fp).toString()); zs.putNextEntry(zipEntry); try (FileInputStream fs = new FileInputStream(fp.toFile())) { IOUtils.copy(fs, zs); } zs.closeEntry();` – Keshav Jun 20 '17 at 04:00
  • 1
    instead of `zs.write` one can make use of `Files.copy(path, zs)`, which is almost guaranteed to reduce memory footprint – Vogel612 Sep 26 '17 at 10:47
  • 5
    `throw new RuntimeException(e)` is better than `System.err.println(e)` – The Alchemist Mar 16 '18 at 21:57
  • 1
    Thank you for this. When using it I had Sonarqube moan at me about the walk call, saying it should be `try (Stream stream = Files.walk(workingFolder)) { ` so the stream gets closed. – Matt Harrison Apr 16 '18 at 01:28
  • This doesn't add the empty folders. – Roberto Rodriguez Oct 03 '20 at 22:11
  • 1
    You should update this answer to replace \ with / on Windows. Some zip programs don't recognize the \ as a separator. – Earthcomputer Nov 10 '20 at 19:57
70

It can be easily solved by package java.util.Zip no need any extra Jar files

Just copy the following code and run it with your IDE

//Import all needed packages
package general;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipUtils {

    private List <String> fileList;
    private static final String OUTPUT_ZIP_FILE = "Folder.zip";
    private static final String SOURCE_FOLDER = "D:\\Reports"; // SourceFolder path

    public ZipUtils() {
        fileList = new ArrayList < String > ();
    }

    public static void main(String[] args) {
        ZipUtils appZip = new ZipUtils();
        appZip.generateFileList(new File(SOURCE_FOLDER));
        appZip.zipIt(OUTPUT_ZIP_FILE);
    }

    public void zipIt(String zipFile) {
        byte[] buffer = new byte[1024];
        String source = new File(SOURCE_FOLDER).getName();
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        try {
            fos = new FileOutputStream(zipFile);
            zos = new ZipOutputStream(fos);

            System.out.println("Output to Zip : " + zipFile);
            FileInputStream in = null;

            for (String file: this.fileList) {
                System.out.println("File Added : " + file);
                ZipEntry ze = new ZipEntry(source + File.separator + file);
                zos.putNextEntry(ze);
                try {
                    in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
                    int len;
                    while ((len = in .read(buffer)) > 0) {
                        zos.write(buffer, 0, len);
                    }
                } finally {
                    in.close();
                }
            }

            zos.closeEntry();
            System.out.println("Folder successfully compressed");

        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                zos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void generateFileList(File node) {
        // add file only
        if (node.isFile()) {
            fileList.add(generateZipEntry(node.toString()));
        }

        if (node.isDirectory()) {
            String[] subNote = node.list();
            for (String filename: subNote) {
                generateFileList(new File(node, filename));
            }
        }
    }

    private String generateZipEntry(String file) {
        return file.substring(SOURCE_FOLDER.length() + 1, file.length());
    }
}

Refer mkyong..I changed the code for the requirement of current question

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
kark
  • 4,763
  • 6
  • 30
  • 44
  • This creates a folder inside of the zip with the name of the zipped folder. To avoid this, instead of ZipEntry ze = new ZipEntry(source + File.separator + file); use ZipEntry ze = new ZipEntry(file); – Stefa Feb 20 '21 at 11:59
  • This is incompatible between windows and linux/android because node.toString() will provide a environment specific path separator. As a workaround: generateZipEntry(root, node.getAbsolutePath().replaceAll("\\\\", "/")) – Stefa Feb 20 '21 at 17:47
34

Here's a pretty terse Java 7+ solution which relies purely on vanilla JDK classes, no third party libraries required:

public static void pack(final Path folder, final Path zipFilePath) throws IOException {
    try (
            FileOutputStream fos = new FileOutputStream(zipFilePath.toFile());
            ZipOutputStream zos = new ZipOutputStream(fos)
    ) {
        Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                zos.putNextEntry(new ZipEntry(folder.relativize(file).toString()));
                Files.copy(file, zos);
                zos.closeEntry();
                return FileVisitResult.CONTINUE;
            }

            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                zos.putNextEntry(new ZipEntry(folder.relativize(dir).toString() + "/"));
                zos.closeEntry();
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

It copies all files in folder, including empty directories, and creates a zip archive at zipFilePath.

Javo
  • 435
  • 1
  • 5
  • 16
jjst
  • 2,631
  • 2
  • 22
  • 34
  • this method has some problem if you create zip on window and use this zip on linux ! – aeroxr1 May 19 '16 at 05:25
  • 2
    Can you be more specific? What kind of problems are you running into? – jjst May 23 '16 at 22:24
  • 1
    Method Fonder.relativize(dir) use system separator and in the Windows case it is \ and this is a problem when you generate a zip on window system and use it on unix system. You will see files outside the its folders . There is other problem, on Linux previsitDirectory also visit the " " directory and in this way if you zip the Folder in a zip named "test.zip" on Linux system inside that zip you will find all the files plus a empty folder named "test" – aeroxr1 May 24 '16 at 03:23
  • 1
    Can you try to replace `zos.putNextEntry(new ZipEntry(folder.relativize(file).toString()));` with `zos.putNextEntry(new ZipEntry(folder.relativize(file).toString().replace("\\","/")));`, see if it gets around the Windows-path issue? If so I'll update the answer. I haven't managed to reproduce your other issue. – jjst May 24 '16 at 22:18
  • 3
    This worked for me without problems on windows, just skipping the override for "preVisitDirectory" worked for me (because it is relative, all subfolders are generated). There is only one downside as far as I can think of: empty folders are getting skipped – FibreFoX Jun 14 '16 at 08:10
  • rather than return void, and throw exception, you should return exception or null and throw nothing. This style of coding a void function call is much better than than 1,000 try/catch blocks. – Hypersoft Systems Nov 06 '17 at 16:23
14

Java 7+, commons.io

public final class ZipUtils {

    public static void zipFolder(final File folder, final File zipFile) throws IOException {
        zipFolder(folder, new FileOutputStream(zipFile));
    }

    public static void zipFolder(final File folder, final OutputStream outputStream) throws IOException {
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
            processFolder(folder, zipOutputStream, folder.getPath().length() + 1);
        }
    }

    private static void processFolder(final File folder, final ZipOutputStream zipOutputStream, final int prefixLength)
            throws IOException {
        for (final File file : folder.listFiles()) {
            if (file.isFile()) {
                final ZipEntry zipEntry = new ZipEntry(file.getPath().substring(prefixLength));
                zipOutputStream.putNextEntry(zipEntry);
                try (FileInputStream inputStream = new FileInputStream(file)) {
                    IOUtils.copy(inputStream, zipOutputStream);
                }
                zipOutputStream.closeEntry();
            } else if (file.isDirectory()) {
                processFolder(file, zipOutputStream, prefixLength);
            }
        }
    }
}
Tony BenBrahim
  • 7,040
  • 2
  • 36
  • 49
  • 2
    If you want to remove dependency on commons.io, the `IOUtils.copy` method is pretty much just: `byte [] buffer = new byte[1024 * 4]; int read = 0; while ((read = input.read(buffer)) != -1) { output.write(buffer, 0, read); }` – Mark Rhodes Apr 22 '15 at 15:36
10

I usually use a helper class I once wrote for this task:

import java.util.zip.*;
import java.io.*;

public class ZipExample {
    public static void main(String[] args){
        ZipHelper zippy = new ZipHelper();
        try {
            zippy.zipDir("folderName","test.zip");
        } catch(IOException e2) {
            System.err.println(e2);
        }
    }
}

class ZipHelper  
{
    public void zipDir(String dirName, String nameZipFile) throws IOException {
        ZipOutputStream zip = null;
        FileOutputStream fW = null;
        fW = new FileOutputStream(nameZipFile);
        zip = new ZipOutputStream(fW);
        addFolderToZip("", dirName, zip);
        zip.close();
        fW.close();
    }

    private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws IOException {
        File folder = new File(srcFolder);
        if (folder.list().length == 0) {
            addFileToZip(path , srcFolder, zip, true);
        }
        else {
            for (String fileName : folder.list()) {
                if (path.equals("")) {
                    addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, false);
                } 
                else {
                     addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, false);
                }
            }
        }
    }

    private void addFileToZip(String path, String srcFile, ZipOutputStream zip, boolean flag) throws IOException {
        File folder = new File(srcFile);
        if (flag) {
            zip.putNextEntry(new ZipEntry(path + "/" +folder.getName() + "/"));
        }
        else {
            if (folder.isDirectory()) {
                addFolderToZip(path, srcFile, zip);
            }
            else {
                byte[] buf = new byte[1024];
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
                while ((len = in.read(buf)) > 0) {
                    zip.write(buf, 0, len);
                }
            }
        }
    }
}
halex
  • 16,253
  • 5
  • 58
  • 67
9

Enhanced Java 8+ example (Forked from Nikita Koksharov's answer)

public static void pack(String sourceDirPath, String zipFilePath) throws IOException {
    Path p = Files.createFile(Paths.get(zipFilePath));
    Path pp = Paths.get(sourceDirPath);
    try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p));
        Stream<Path> paths = Files.walk(pp)) {
        paths
          .filter(path -> !Files.isDirectory(path))
          .forEach(path -> {
              ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
              try {
                  zs.putNextEntry(zipEntry);
                  Files.copy(path, zs);
                  zs.closeEntry();
            } catch (IOException e) {
                System.err.println(e);
            }
          });
    }
}

Files.walk has been wrapped in try with resources block so that stream can be closed. This resolves blocker issue identified by SonarQube. Thanks @Matt Harrison for pointing this.

Abdul Rauf
  • 5,798
  • 5
  • 50
  • 70
  • The forEach here won't be closed, what's the problem with that? – Elik Mar 26 '19 at 08:20
  • @Elik everything was fine the last time I checked. What do you mean by "The forEach here won't be closed"? – Abdul Rauf Mar 26 '19 at 08:55
  • I mean forEach seems not to be closed, so it stucks in the end and the execution won't be terminated. – Elik Mar 26 '19 at 09:55
  • @Elik ensure that you are passing valid sourceDirPath and zipFilePath. Something like `pack("D:\\reports\\january\\", "D:\\reports\\january.zip");` Its only you since [the answer I forked from](https://stackoverflow.com/questions/15968883/how-to-zip-a-folder-itself-using-java/32052016#32052016) has been upvoted almost 62 times. – Abdul Rauf Mar 26 '19 at 12:46
5

Using zip4j you can simply do this

ZipFile zipfile = new ZipFile(new File("D:\\reports\\january\\filename.zip"));
zipfile.addFolder(new File("D:\\reports\\january\\"));

It will archive your folder and everything in it.

Use the .extractAll method to get it all out:

zipfile.extractAll("D:\\destination_directory");
svarog
  • 9,477
  • 4
  • 61
  • 77
4

I would use Apache Ant, which has an API to call tasks from Java code rather than from an XML build file.

Project p = new Project();
p.init();
Zip zip = new Zip();
zip.setProject(p);
zip.setDestFile(zipFile); // a java.io.File for the zip you want to create
zip.setBasedir(new File("D:\\reports"));
zip.setIncludes("january/**");
zip.perform();

Here I'm telling it to start from the base directory D:\reports and zip up the january folder and everything inside it. The paths in the resulting zip file will be the same as the original paths relative to D:\reports, so they will include the january prefix.

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
2

Try this:

 import java.io.File;

 import java.io.FileInputStream;

 import java.io.FileOutputStream;

 import java.util.zip.ZipEntry;

 import java.util.zip.ZipOutputStream;


  public class Zip {

public static void main(String[] a) throws Exception {

    zipFolder("D:\\reports\\january", "D:\\reports\\january.zip");

  }

  static public void zipFolder(String srcFolder, String destZipFile) throws Exception {
    ZipOutputStream zip = null;
    FileOutputStream fileWriter = null;
    fileWriter = new FileOutputStream(destZipFile);
    zip = new ZipOutputStream(fileWriter);
    addFolderToZip("", srcFolder, zip);
    zip.flush();
    zip.close();
  }
  static private void addFileToZip(String path, String srcFile, ZipOutputStream zip)
      throws Exception {
    File folder = new File(srcFile);
    if (folder.isDirectory()) {
      addFolderToZip(path, srcFile, zip);
    } else {
      byte[] buf = new byte[1024];
      int len;
      FileInputStream in = new FileInputStream(srcFile);
      zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
      while ((len = in.read(buf)) > 0) {
        zip.write(buf, 0, len);
      }
    }
  }

  static private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip)
      throws Exception {
    File folder = new File(srcFolder);

    for (String fileName : folder.list()) {
      if (path.equals("")) {
        addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);
      } else {
        addFileToZip(path + "/" + folder.getName(), srcFolder + "/" +   fileName, zip);
      }
    }
  }



   }
Denis
  • 390
  • 3
  • 14
1

Java 6 +

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Zip {

    private static final FileFilter FOLDER_FILTER = new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isDirectory();
        }
    };

    private static final FileFilter FILE_FILTER = new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isFile();
        }
    };


    private static void compress(File file, ZipOutputStream outputStream, String path) throws IOException {

        if (file.isDirectory()) {
            File[] subFiles = file.listFiles(FILE_FILTER);
            if (subFiles != null) {
                for (File subFile : subFiles) {
                    compress(subFile, outputStream, new File(path, subFile.getName()).getAbsolutePath());
                }
            }
            File[] subDirs = file.listFiles(FOLDER_FILTER);
            if (subDirs != null) {
                for (File subDir : subDirs) {
                    compress(subDir, outputStream, new File(path, subDir.getName()).getAbsolutePath());
                }
            }
        } else if (file.exists()) {
            outputStream.putNextEntry(new ZipEntry(path));
            FileInputStream inputStream = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) >= 0) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.closeEntry();
        }
    }

    public static void compress(String dirPath, String zipFilePath) throws IOException {
        File file = new File(dirPath);
        final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFilePath));
        compress(file, outputStream, "/");
        outputStream.close();
    }

}
Dillion Wang
  • 362
  • 3
  • 18
1

I found this solution worked perfectly fine for me. Doesn't require any third party apis

'test' is actually a folder will lots of file inside.

String folderPath= "C:\Users\Desktop\test";
String zipPath = "C:\Users\Desktop\test1.zip";

private boolean zipDirectory(String folderPath, String zipPath) throws IOException{

        byte[] buffer = new byte[1024];
        FileInputStream fis = null;
        ZipOutputStream zos = null;

        try{
            zos = new ZipOutputStream(new FileOutputStream(zipPath));
            updateSourceFolder(new File(folderPath));

            if (sourceFolder == null) {
                zos.close();
                return false;
            }
            generateFileAndFolderList(new File(folderPath));

            for (String unzippedFile: fileList) {
                System.out.println(sourceFolder + unzippedFile);

                ZipEntry entry = new ZipEntry(unzippedFile);
                zos.putNextEntry(entry);

                if ((unzippedFile.substring(unzippedFile.length()-1)).equals(File.separator))
                    continue;
                try{
                    fis = new FileInputStream(sourceFolder + unzippedFile);
                    int len=0;
                    while ((len = fis.read(buffer))>0) {
                        zos.write(buffer,0,len);
                    }
                } catch(IOException e) {
                    return false;
                } finally {
                    if (fis != null)
                        fis.close();
                }
            }
            zos.closeEntry();
        } catch(IOException e) {
            return false;
        } finally {
            zos.close();
            fileList = null;
            sourceFolder = null;
        }
        return true;
    }

    private void generateFileAndFolderList(File node) {
        if (node.isFile()) {
            fileList.add(generateZipEntry(node.getAbsoluteFile().toString()));
        }
        if (node.isDirectory()) {
            String dir = node.getAbsoluteFile().toString();
            fileList.add(dir.substring(sourceFolder.length(), dir.length()) + File.separator);

            String[] subNode = node.list();
            for (String fileOrFolderName : subNode) {
                generateFileAndFolderList(new File(node, fileOrFolderName));
            }
        }
    }

    private void updateSourceFolder(File node) {
        if (node.isFile() || node.isDirectory()) {
            String sf = node.getAbsoluteFile().toString();
            sourceFolder = sf.substring(0, (sf.lastIndexOf("/") > 0 ? sf.lastIndexOf("/") : sf.lastIndexOf("\\")));
            sourceFolder += File.separator;
        } else
            sourceFolder = null;
    }

    private String generateZipEntry(String file) {
        return file.substring(sourceFolder.length(), file.length());
    }
user3336194
  • 79
  • 1
  • 1
  • 11
1

This method zips a folder and adds all of the child files & folders (including empty folders) into the zip file.

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();

}

And here is the ZipDirectoryVisitor implementation:

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;
    }
}
0

I have modified the above solutions and replaced Files.walk with Files.list. This also assumes the directory you are zipping only contains file and not any sub directories.

private void zipDirectory(Path dirPath) throws IOException {
        String zipFilePathStr = dirPath.toString() + ".zip";
        Path zipFilePath = Files.createFile(Paths.get(zipFilePathStr));

        try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(zipFilePath))) {
            Files.list(dirPath)
                .filter(filePath-> !Files.isDirectory(filePath))
                .forEach(filePath-> {
                    ZipEntry zipEntry = new ZipEntry(dirPath.relativize(filePath).toString());
                    try {
                        zs.putNextEntry(zipEntry);
                        Files.copy(filePath, zs);
                        zs.closeEntry();
                    }
                    catch (IOException e) {
                        System.err.println(e);
                    }
                });
        }
    }
chomprrr
  • 406
  • 4
  • 15
0

Improving @Nikita Koksharov's code had problems packing empty directories.

private void zipDirectory(OutputStream outputStream, Path directoryPath) throws IOException {
    try (ZipOutputStream zs = new ZipOutputStream(outputStream)) {
        Path pp = directoryPath;
        Files.walk(pp)
                .forEach(path -> {
                    try {
                        if (Files.isDirectory(path)) {
                            zs.putNextEntry(new ZipEntry(pp.relativize(path).toString() + "/"));
                        } else {
                            ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
                            zs.putNextEntry(zipEntry);
                            Files.copy(path, zs);
                            zs.closeEntry();
                        }
                    } catch (IOException e) {
                        System.err.println(e);
                    }
                });
    }
}

Test usage

    FileOutputStream zipOutput = new FileOutputStream("path_to_file.zip");
    Path pathOutput = Path.of("path_directory_fid");
    zipDirectory(outputStream, pathOutput);
Ronald Coarite
  • 4,460
  • 27
  • 31
0

try this zip("C:\testFolder", "D:\testZip.zip")

public void zip( String sourcDirPath,  String zipPath) throws IOException {
  Path zipFile = Files.createFile(Paths.get(zipPath));

  Path sourceDirPath = Paths.get(sourcDirPath);
  try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile));
       Stream<Path> paths = Files.walk(sourceDirPath)) {
      paths
              .filter(path -> !Files.isDirectory(path))
              .forEach(path -> {
                  ZipEntry zipEntry = new ZipEntry(sourceDirPath.relativize(path).toString());
                  try {
                      zipOutputStream.putNextEntry(zipEntry);
                      Files.copy(path, zipOutputStream);
                      zipOutputStream.closeEntry();
                  } catch (IOException e) {
                      System.err.println(e);
                  }
              });
  }

  System.out.println("Zip is created at : "+zipFile);
}
Rahul_Mandhane
  • 187
  • 1
  • 11