【问题标题】:how to zip a folder itself using java如何使用java压缩文件夹本身
【发布时间】:2013-04-04 20:01:51
【问题描述】:

假设我有以下目录结构。

D:\reports\january\

一月内假设有两个 excel 文件,分别是 A.xls 和 B.xls。很多地方都写过如何使用java.util.zip 压缩文件。但我想将一月文件夹本身压缩到报告文件夹中,以便 januaryjanuary.zip 都将出现在报告中。 (这意味着当我解压缩 january.zip 文件时,我应该得到 january 文件夹)。

任何人都可以使用java.util.zip 向我提供执行此操作的代码。请让我知道这是否可以通过使用其他库更轻松地完成。

非常感谢...

【问题讨论】:

  • 为什么版主不关闭这类问题,它直接违反了第一页的规则“不要问...你没有试图找到答案的问题(显示你的工作!)”。

标签: java zip directory


【解决方案1】:

试试这个 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);
}

【讨论】:

    【解决方案2】:

    改进@Nikita Koksharov 的代码在打包空目录时遇到问题。

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

    测试使用

        FileOutputStream zipOutput = new FileOutputStream("path_to_file.zip");
        Path pathOutput = Path.of("path_directory_fid");
        zipDirectory(outputStream, pathOutput);
    

    【讨论】:

      【解决方案3】:

      我已经修改了上面的解决方案,将Files.walk替换为Files.list。这也假设您要压缩的目录仅包含文件而不包含任何子目录。

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

      【讨论】:

        【解决方案4】:

        使用zip4j 你可以简单地做到这一点

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

        它将归档您的文件夹及其中的所有内容。

        使用.extractAll 方法将其全部显示出来:

        zipfile.extractAll("D:\\destination_directory");
        

        【讨论】:

          【解决方案5】:

          增强的 Java 8+ 示例(来自 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 已包装在 try with resources 块中,以便可以关闭流。这解决了SonarQube 确定的阻止程序问题。 感谢@Matt Harrison 指出这一点。

          【讨论】:

          • 这里的forEach不会关闭,有什么问题?
          • @Elik 我上次检查时一切正常。 “这里的 forEach 不会关闭”是什么意思?
          • 我的意思是forEach好像没有关闭,所以卡在最后,执行也不会终止。
          • @Elik 确保您传递了有效的 sourceDirPath 和 zipFilePath。 pack("D:\\reports\\january\\", "D:\\reports\\january.zip"); 之类的东西,自从 the answer I forked from 以来,只有你一个人被投票了近 62 次。
          【解决方案6】:

          java.util.Zip可以轻松解决,不需要额外的Jar文件

          只需复制以下代码和run it 与您的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());
              }
          }
          

          参考mkyong..我为当前问题的要求更改了代码

          【讨论】:

          • 这会在 zip 中创建一个文件夹,其中包含压缩文件夹的名称。为了避免这种情况,而不是 ZipEntry ze = new ZipEntry(source + File.separator + file);使用 ZipEntry ze = new ZipEntry(file);
          • 这在 windows 和 linux/android 之间是不兼容的,因为 node.toString() 将提供一个特定于环境的路径分隔符。作为一种解决方法: generateZipEntry(root, node.getAbsolutePath().replaceAll("\\\\", "/"))
          【解决方案7】:

          此方法压缩文件夹并将所有子文件和文件夹(包括空文件夹)添加到 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;
              }
          }
          

          【讨论】:

            【解决方案8】:

            我发现这个解决方案对我来说非常有效。不需要任何第三方api

            'test'实际上是一个文件夹,里面有很多文件。

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

            【讨论】:

              【解决方案9】:

              这是 Java 8+ 示例:

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

              【讨论】:

              • 小改进:将 ZipOutpuStream 放入 try (...) { };对于 sp,我添加了 .replace("\\", "/");将 sp + "/" + path... 替换为 sp + path...
              • 获取ZipEntry的相对路径可以简化为new ZipEntry(pp.relativize(path).toString())
              • 如果文件很大,Files.readAllBytes() 不会导致内存膨胀吗?
              • @Keshav 你是对的,你能提出任何解决方案吗?
              • throw new RuntimeException(e) 优于 System.err.println(e)
              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

                这是一个非常简洁的 Java 7+ 解决方案,它完全依赖于普通 JDK 类,不需要第三方库:

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

                它复制folder 中的所有文件,包括空目录,并在zipFilePath 创建一个zip 存档。

                【讨论】:

                • 如果你在window上创建zip并在linux上使用这个zip,这个方法会有问题!
                • 你能说得更具体点吗?你遇到了什么样的问题?
                • Method Fonder.relativize(dir) 使用系统分隔符,在 Windows 的情况下是 \,当您在窗口系统上生成 zip 并在 unix 系统上使用它时,这是一个问题。您将看到其文件夹之外的文件。还有其他问题,在 Linux previsitDirectory 上也访问“”目录,这样,如果您在 Linux 系统上将文件夹压缩到名为“test.zip”的 zip 中,您将在该 zip 中找到所有文件以及一个名为“的空文件夹”测试”
                • 您可以尝试将zos.putNextEntry(new ZipEntry(folder.relativize(file).toString())); 替换为zos.putNextEntry(new ZipEntry(folder.relativize(file).toString().replace("\\","/")));,看看是否可以解决Windows 路径问题?如果是这样,我会更新答案。我没有设法重现您的其他问题。
                • 这对我有用,在 Windows 上没有问题,只是跳过对“preVisitDirectory”的覆盖对我有用(因为它是相对的,所以会生成所有子文件夹)。据我所知,只有一个缺点:空文件夹被跳过
                【解决方案12】:

                您尝试过Zeroturnaround Zip 库吗?真的很整洁!压缩文件夹只是一个衬里:

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

                (感谢Oleg Šelajev的例子)

                【讨论】:

                • 如果我需要再添加一个文件,在文件夹级别如何使用这个库来完成
                • 创建一个文件数组 ZipEntrySource[] arr 然后使用这个方法: ZipUtil.pack(arr, new File(outZipPath))
                【解决方案13】:

                试试这个:

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

                【讨论】:

                  【解决方案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);
                              }
                          }
                      }
                  }
                  

                  【讨论】:

                  • 如果你想移除对 commons.io 的依赖,IOUtils.copy 方法很简单:byte [] buffer = new byte[1024 * 4]; int read = 0; while ((read = input.read(buffer)) != -1) { output.write(buffer, 0, read); }
                  【解决方案15】:

                  我通常使用我曾经为此任务编写的辅助类:

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

                  【讨论】:

                  • 您应该在完成后关闭 FileInputStream 的输入流。
                  【解决方案16】:

                  我会使用Apache Ant,它有一个 API 可以从 Java 代码而不是 XML 构建文件调用任务。

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

                  这里我告诉它从基本目录D:\reports 开始,然后压缩january 文件夹和其中的所有内容。生成的 zip 文件中的路径将与相对于 D:\reports 的原始路径相同,因此它们将包含 january 前缀。

                  【讨论】:

                  • 我的org.apache.ant.compress.taskdefs.Zip 版本(org.apache.ant:ant-compress:1.5)没有setBasedir
                  猜你喜欢
                  • 1970-01-01
                  • 2022-07-27
                  • 1970-01-01
                  • 2012-01-23
                  • 2017-05-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-09-17
                  相关资源
                  最近更新 更多