【问题标题】:directories in a zip file when using java.util.zip.ZipOutputStream使用 java.util.zip.ZipOutputStream 时 zip 文件中的目录
【发布时间】:2009-04-11 16:24:25
【问题描述】:

假设我有一个文件 t.txt、一个目录 t 和另一个文件 t/t2.txt。如果我使用 linux zip 实用程序“zip -r t.zip t.txt t”,我会得到一个 zip 文件,其中包含以下条目(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

如果我尝试使用 java.util.zip.ZipOutputStream 复制该行为并为目录创建一个 zip 条目,java 会引发异常。它只能处理文件。我可以在 zip 文件中创建一个 t/t2.txt 条目并将使用 t2.txt 文件内容添加到其中,但我无法创建目录。这是为什么呢?

【问题讨论】:

    标签: java directory zip


    【解决方案1】:

    ZipOutputStream 可以通过在文件夹名称后添加正斜杠 / 来处理空目录。试试(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());
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      就像其他人在这里所说的添加空目录添加“/”到目录名称。 注意不要添加 File.separator(等于“\”),它实际上是在 zip 中添加一个空文件。

      我花了一段时间才明白我的错误 - 希望我能节省一些时间......

      【讨论】:

      • 是的,你确实为我节省了一些时间。在阅读答案时,我在想“是的!我知道得更好:我将使用 File.Separator 来实现‘便携’并有更好的实现。”非常感谢。
      【解决方案3】:

      只需浏览 java.util.zip.ZipEntry 的源代码即可。如果 ZipEntry 的名称以“/”字符结尾,它会将其视为目录。只需在目录名称后加上“/”即可。

      查看此示例以仅压缩空目录, http://bethecoder.com/applications/tutorials/showTutorials.action?tutorialId=Java_ZipUtilities_ZipEmptyDirectory

      祝你好运。

      【讨论】:

        【解决方案4】:

        您可以在文件夹名称的末尾添加“/”。只需使用以下命令:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 您没有向 ZIP 文件添加任何目录条目,这是 OP 要求的,这个答案根本不适用。
          【解决方案6】:

          Java 程序到 Zip(文件夹包含空的或完整的)

          public class ZipUsingJavaUtil {
              /*
               * Zip function zip all files and folders
               */
              @Override
              @SuppressWarnings("finally")
              public boolean zipFiles(String srcFolder, String destZipFile) {
                  boolean result = false;
                  try {
                      System.out.println("Program Start zipping the given files");
                      /*
                       * send to the zip procedure
                       */
                      zipFolder(srcFolder, destZipFile);
                      result = true;
                      System.out.println("Given files are successfully zipped");
                  } catch (Exception e) {
                      System.out.println("Some Errors happned during the zip process");
                  } finally {
                      return result;
                  }
              }
          
              /*
               * zip the folders
               */
              private void zipFolder(String srcFolder, String destZipFile) throws Exception {
                  ZipOutputStream zip = null;
                  FileOutputStream fileWriter = null;
                  /*
                   * create the output stream to zip file result
                   */
                  fileWriter = new FileOutputStream(destZipFile);
                  zip = new ZipOutputStream(fileWriter);
                  /*
                   * add the folder to the zip
                   */
                  addFolderToZip("", srcFolder, zip);
                  /*
                   * close the zip objects
                   */
                  zip.flush();
                  zip.close();
              }
          
              /*
               * recursively add files to the zip files
               */
              private void addFileToZip(String path, String srcFile, ZipOutputStream zip, boolean flag) throws Exception {
                  /*
                   * create the file object for inputs
                   */
                  File folder = new File(srcFile);
          
                  /*
                   * if the folder is empty add empty folder to the Zip file
                   */
                  if (flag == true) {
                      zip.putNextEntry(new ZipEntry(path + "/" + folder.getName() + "/"));
                  } else { /*
                           * if the current name is directory, recursively traverse it
                           * to get the files
                           */
                      if (folder.isDirectory()) {
                          /*
                           * if folder is not empty
                           */
                          addFolderToZip(path, srcFile, zip);
                      } else {
                          /*
                           * write the file to the output
                           */
                          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) {
                              /*
                               * Write the Result
                               */
                              zip.write(buf, 0, len);
                          }
                      }
                  }
              }
          
              /*
               * add folder to the zip file
               */
              private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception {
                  File folder = new File(srcFolder);
          
                  /*
                   * check the empty folder
                   */
                  if (folder.list().length == 0) {
                      System.out.println(folder.getName());
                      addFileToZip(path, srcFolder, zip, true);
                  } else {
                      /*
                       * list the files in the folder
                       */
                      for (String fileName : folder.list()) {
                          if (path.equals("")) {
                              addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, false);
                          } else {
                              addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, false);
                          }
                      }
                  }
              }
          }
          

          【讨论】:

          • 你应该关闭你的 FileInputStream
          • 总之,你应该关闭 FileInputStream。不过,这真是太好了!
          • 一项 API 改进:有一个 zipFiles(final String[] srcFolders, final String destZipFile) 可以在您的 zip 文件中添加多个文件夹。只需在zipFolder-方法中添加一个for循环即可。使用这些方法很容易将单个和多个文件夹添加到 zip 文件中。
          猜你喜欢
          • 1970-01-01
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多