用java解压包含子文件夹的存档?

用java解压包含子文件夹的存档?,java,zip,unzip,zipinputstream,Java,Zip,Unzip,Zipinputstream,我正在尝试解压缩一个包含一些png图像的子文件夹的存档(test.zip): test.zip | -> images | -> a.png | -> b.png 以下是我的工作: public static void unzip(String archive, File baseFolder, String[] ignoreExtensions) { FileInputStream fin; try {

我正在尝试解压缩一个包含一些png图像的子文件夹的存档(test.zip):

test.zip
  | -> images
         | -> a.png
         | -> b.png
以下是我的工作:

  public static void unzip(String archive, File baseFolder, String[] ignoreExtensions) {
    FileInputStream fin;
    try {
      fin = new FileInputStream(archive);
      ZipInputStream zin = new ZipInputStream(fin);
      ZipEntry ze = null;
      while ((ze = zin.getNextEntry()) != null) {
        if (ignoreExtensions == null || !ignoreEntry(ze, ignoreExtensions)) {
          File destinationFile = new File(baseFolder, ze.getName());
          unpackEntry(destinationFile, zin);
        }
      }
      zin.close();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  private static void unpackEntry(File destinationFile, ZipInputStream zin) {
    createParentFolder(destinationFile);
    FileOutputStream fout = null;
    try {
      fout = new FileOutputStream(destinationFile);
      for (int c = zin.read(); c != -1; c = zin.read()) {
        fout.write(c);
        zin.closeEntry();
        fout.close();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }

  }

  private static void createParentFolder(File destinationFile) {
    File parent = new File(destinationFile.getParent());
    parent.mkdirs();
  }
图像被提取到正确的位置,但已损坏(大小比预期的小,因此我假设它们未解压缩)


如果我用7Zip打开test.zip文件,它可以正常工作。有没有关于如何解压包含子文件夹的存档的想法?

您在这里做什么

  for (int c = zin.read(); c != -1; c = zin.read()) {
    fout.write(c);
    zin.closeEntry();
    fout.close();
  }
难道你是说这个吗

  for (int c = zin.read(); c != -1; c = zin.read()) {
    fout.write(c);
  }
  zin.closeEntry();
  fout.close();

通过检查解压后的条目是否为目录,可以按如下方式完成。如果是目录,则创建目录,并继续在目录内对文件进行流式处理

private void unZipFile(long lBatchID, String sFileName) throws Exception {
    final int BUFFER = 2048;
    BufferedOutputStream dest = null;
    FileInputStream fis = null;
    ZipInputStream zis = null;
    int iSubstr1 = sFileName.indexOf("-");
    int iSubstr2 = sFileName.lastIndexOf("-");
    int iEDocketSubStr = sFileName.lastIndexOf("\\");
    String sBatchNum = sFileName.substring(iSubstr1 + 1,
            iSubstr2);
    String sEDocketNum = sFileName.substring(iEDocketSubStr + 1,
            iSubstr1);
    Date startTime = new Date();
    try {

        fis = new FileInputStream(sFileName);
        zis = new ZipInputStream(
                new BufferedInputStream(fis));
        ZipEntry entry;
        String sTempDir = TEMP_DIR + "\\" + sEDocketNum+"-"+sBatchNum;
        File fTempDir = new File(sTempDir);
        fTempDir.mkdirs();
        while ((entry = zis.getNextEntry()) != null) {
            int count;
            byte data[] = new byte[BUFFER];
            if(entry.isDirectory())
            {
                File f2 = new File(TEMP_DIR + "\\" + sEDocketNum+"-"+sBatchNum+"\\"+entry.getName());
                f2.mkdir();
                logger.debug("Creating directory during unzip....."+entry.getName());
            }
            else
            {
            FileOutputStream fos = new FileOutputStream(new File(sTempDir
                    + "\\" + entry.getName()));
            dest = new BufferedOutputStream(fos, BUFFER);
            while ((count = zis.read(data, 0, BUFFER)) != -1) {
                dest.write(data, 0, count);
            }
            dest.flush();
            dest.close();
            }
        }
        zis.close();
        LogTaskDuration.logDuration(lBatchID, startTime, "UNZIP");
    } catch (Exception e) {

        e.printStackTrace();
        logger.error("Problem unzipping file - " + sFileName);
        throw new Exception(
                "Could not create temporary directory to unzip file");
    }
    finally
    {
        if(dest != null)
            dest.close();
        if(fis!=null)
            fis.close();

    }
}

此外,为了提高效率,最好在那里使用缓冲数组,而不是单独读取和写入每个字节。(对于正在写入的每个字节,至少有两个本机调用:一个在充气器(zlib)中,一个在FileOutputStream中。本机调用非常昂贵。)