【问题标题】:How to zip files and folders in Java?如何在 Java 中压缩文件和文件夹?
【发布时间】:2015-05-12 06:44:11
【问题描述】:

请看下面的代码。

public void startCompress(String path,String fileName,String outputLocation,int compressType,int filSize) throws Exception
    {        
        System.out.println("Input Location: "+path);
        System.out.println("Output Location: "+outputLocation);   

            System.out.println(compressType);
            byte[] bs=new byte[filSize];
            System.out.println(filSize);

            FileOutputStream fos=new FileOutputStream(outputLocation+"/test.zip");

            System.out.println(fos.toString());
            ZipOutputStream zos=new ZipOutputStream(fos);

            ZipEntry ze = new ZipEntry(fileName);

            zos.putNextEntry(ze);

            FileInputStream inputStream=new FileInputStream(path);

            int len;
            while((len=inputStream.read(bs))>0){
                zos.write(bs, 0, len);                
            }
            inputStream.close();
            zos.closeEntry();
            zos.close();

    }

在上面的代码中,我们使用java.util.zip 包来压缩一个文件。但是我们有一个问题。也就是说,如果我们选择多个文件,那么只有一个文件被压缩。如果我们选择一个文件夹,压缩根本不起作用。

如何解决此问题以压缩文件、文件、文件夹、文件夹甚至嵌套文件夹? Java zip 包支持 .zip、.tar、.tarGz 和 tarZ。因此,解决方案也不应该仅限于 .zip 扩展名。

【问题讨论】:

标签: java io compression zip fileinputstream


【解决方案1】:

这是我使用新 java.nio 包的解决方案。只需调用 zipDir 给它目录的路径。它将在同一位置创建一个名为 <directory>.zip 的 zip 文件。

private static Path buildPath(final Path root, final Path child) {
    if (root == null) {
        return child;
    } else {
        return Paths.get(root.toString(), child.toString());
    }
}

private static void addZipDir(final ZipOutputStream out, final Path root, final Path dir) throws IOException {
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
        for (Path child : stream) {
            Path entry = buildPath(root, child.getFileName());
            if (Files.isDirectory(child)) {
                addZipDir(out, entry, child);
            } else {
                out.putNextEntry(new ZipEntry(entry.toString()));
                Files.copy(child, out);
                out.closeEntry();
            }
        }
    }
}

public static void zipDir(final Path path) throws IOException {
    if (!Files.isDirectory(path)) {
        throw new IllegalArgumentException("Path must be a directory.");
    }

    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path.toString() + ".zip"));

    try (ZipOutputStream out = new ZipOutputStream(bos)) {
        addZipDir(out, path.getFileName(), path);
    }
}

【讨论】:

    【解决方案2】:

    java 的 zip 库不能用于以更简单的方式压缩文件夹,例如 - 压缩此文件夹。

    如果输入的是文件夹或文件,你需要自己做测试。如果它是一个文件 - 将其添加到 zip 中。如果是文件夹 - 迭代文件夹并将每个文件添加到 zip。对于相同的子文件夹。要将多个文件添加到 Zip,您需要为每个文件创建 ZipEntry。

    你可以试试这个对我有用的代码:

    public static void zip(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();
        }
    }
    

    【讨论】:

      【解决方案3】:

      this answer 更新,修复了将每个文件添加到其自己的目录的问题。也更好地支持 Windows 资源管理器。

      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 Test {
      
          public static void main(String agrs[]) {
              ZipUtils appZip = new ZipUtils();
              appZip.zipIt(new File(source directory), new File(dest zip));
          }
      
          public static class ZipUtils {
      
              private final List<File> fileList;
      
              private List<String> paths;
      
              public ZipUtils() {
                  fileList = new ArrayList<>();
                  paths = new ArrayList<>(25);
              }
      
              public void zipIt(File sourceFile, File zipFile) {
                  if (sourceFile.isDirectory()) {
                      byte[] buffer = new byte[1024];
                      FileOutputStream fos = null;
                      ZipOutputStream zos = null;
      
                      try {
      
                          // This ensures that the zipped files are placed
                          // into a folder, within the zip file
                          // which is the same as the one been zipped
                          String sourcePath = sourceFile.getParentFile().getPath();
                          generateFileList(sourceFile);
      
                          fos = new FileOutputStream(zipFile);
                          zos = new ZipOutputStream(fos);
      
                          System.out.println("Output to Zip : " + zipFile);
                          FileInputStream in = null;
      
                          for (File file : this.fileList) {
                              String path = file.getParent().trim();
                              path = path.substring(sourcePath.length());
      
                              if (path.startsWith(File.separator)) {
                                  path = path.substring(1);
                              }
      
                              if (path.length() > 0) {
                                  if (!paths.contains(path)) {
                                      paths.add(path);
                                      ZipEntry ze = new ZipEntry(path + "/");
                                      zos.putNextEntry(ze);
                                      zos.closeEntry();
                                  }
                                  path += "/";
                              }
      
                              String entryName = path + file.getName();
                              System.out.println("File Added : " + entryName);
                              ZipEntry ze = new ZipEntry(entryName);
      
                              zos.putNextEntry(ze);
                              try {
                                  in = new FileInputStream(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();
                          }
                      }
                  }
              }
      
              protected void generateFileList(File node) {
      
      // add file only
                  if (node.isFile()) {
                      fileList.add(node);
      
                  }
      
                  if (node.isDirectory()) {
                      File[] subNote = node.listFiles();
                      for (File filename : subNote) {
                          generateFileList(filename);
                      }
                  }
              }
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2010-12-14
        • 2010-09-05
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 1970-01-01
        • 2014-04-23
        • 1970-01-01
        相关资源
        最近更新 更多