Java ZIP - 如何解压缩文件夹?

问题描述 投票:18回答:6

有没有示例代码,如何将文件夹从ZIP部分解压缩到我想要的目录?我已将文件夹“FOLDER”中的所有文件读入字节数组,如何从其文件结构中创建?

java zip
6个回答
28
投票

我不确定你的意思是什么?你的意思是没有API帮助自己做吗?

如果你不介意使用一些开源库,那里有一个很酷的API叫做qazxsw poi

它易于使用,我认为有很好的反馈。看这个例子:

zip4J

如果要解压缩的文件有密码,可以试试这个:

String source = "folder/source.zip";
String destination = "folder/source/";   

try {
    ZipFile zipFile = new ZipFile(source);
    zipFile.extractAll(destination);
} catch (ZipException e) {
    e.printStackTrace();
}

我希望这很有用。


22
投票

这是我正在使用的代码。根据您的需要更改BUFFER_SIZE。

String source = "folder/source.zip";
String destination = "folder/source/";
String password = "password";

try {
    ZipFile zipFile = new ZipFile(source);
    if (zipFile.isEncrypted()) {
        zipFile.setPassword(password);
    }
    zipFile.extractAll(destination);
} catch (ZipException e) {
    e.printStackTrace();
}

11
投票

使用Ant Compress库可以实现相同。它将保留文件夹结构。

Maven依赖: -

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipUtils
{
  private static final int  BUFFER_SIZE = 4096;

  private static void extractFile(ZipInputStream in, File outdir, String name) throws IOException
  {
    byte[] buffer = new byte[BUFFER_SIZE];
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(outdir,name)));
    int count = -1;
    while ((count = in.read(buffer)) != -1)
      out.write(buffer, 0, count);
    out.close();
  }

  private static void mkdirs(File outdir,String path)
  {
    File d = new File(outdir, path);
    if( !d.exists() )
      d.mkdirs();
  }

  private static String dirpart(String name)
  {
    int s = name.lastIndexOf( File.separatorChar );
    return s == -1 ? null : name.substring( 0, s );
  }

  /***
   * Extract zipfile to outdir with complete directory structure
   * @param zipfile Input .zip file
   * @param outdir Output directory
   */
  public static void extract(File zipfile, File outdir)
  {
    try
    {
      ZipInputStream zin = new ZipInputStream(new FileInputStream(zipfile));
      ZipEntry entry;
      String name, dir;
      while ((entry = zin.getNextEntry()) != null)
      {
        name = entry.getName();
        if( entry.isDirectory() )
        {
          mkdirs(outdir,name);
          continue;
        }
        /* this part is necessary because file entry can come before
         * directory entry where is file located
         * i.e.:
         *   /foo/foo.txt
         *   /foo/
         */
        dir = dirpart(name);
        if( dir != null )
          mkdirs(outdir,dir);

        extractFile(zin, outdir, name);
      }
      zin.close();
    } 
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}

示例代码: -

<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant-compress</artifactId>
    <version>1.2</version>
</dependency>

4
投票

这是一个简单的解决方案,遵循更现代的惯例。如果要解压缩较大的文件,可能需要将缓冲区大小更改为更小。这样您就不会将所有文件信息保存在内存中。

Unzip unzipper = new Unzip();
unzipper.setSrc(theZIPFile);
unzipper.setDest(theTargetFolder);
unzipper.execute();

1
投票

这里是更加“现代”的完整代码基于 public static void unzip(File source, String out) throws IOException { try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source))) { ZipEntry entry = zis.getNextEntry(); while (entry != null) { File file = new File(out, entry.getName()); if (entry.isDirectory()) { file.mkdirs(); } else { File parent = file.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) { byte[] buffer = new byte[Math.toIntExact(entry.getSize())]; int location; while ((location = zis.read(buffer)) != -1) { bos.write(buffer, 0, location); } } } entry = zis.getNextEntry(); } } } 帖子但重构(并使用this):

Lombok

0
投票

您应该从zip文件中获取所有条目:

import lombok.var;
import lombok.val;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipInputStream;

import static java.nio.file.Files.createDirectories;

public class UnZip
{
    public static void unZip(String sourceZipFile, String outputDirectory) throws IOException
    {
        val folder = new File(outputDirectory);
        createDirectories(folder.toPath());

        try (val zipInputStream = new ZipInputStream(new FileInputStream(sourceZipFile, Charset.forName("Cp437"))))
        {
            var nextEntry = zipInputStream.getNextEntry();

            while (nextEntry != null)
            {
                val fileName = nextEntry.getName();
                val newFile = new File(outputDirectory + File.separator + fileName);

                newFile.getParentFile().mkdirs();

                if(fileName.endsWith("/")){
                    newFile.mkdirs();
                } else {
                    writeFile(zipInputStream, newFile);
                }

                writeFile(zipInputStream, newFile);

                nextEntry = zipInputStream.getNextEntry();
            }

            zipInputStream.closeEntry();
        }
    }

    private static void writeFile(ZipInputStream inputStream, File file) throws IOException
    {
        val buffer = new byte[1024];
        file.createNewFile();
        try (val fileOutputStream = new FileOutputStream(file))
        {
            int length;
            while ((length = inputStream.read(buffer)) > 0)
            {
                fileOutputStream.write(buffer, 0, length);
            }
        }
    }
}

然后itareting这个枚举从它获取Enumeration entries = zipFile.getEntries(); ,检查它是否是一个目录,并创建dirctrory或只是分别提取文件。

© www.soinside.com 2019 - 2024. All rights reserved.