English 中文(简体)
Java ZIP - 如何解脱手脚?
原标题:Java ZIP - how to unzip folder?
  • 时间:2012-05-17 10:05:54
  •  标签:
  • java
  • zip

是否有任何样本代码,如何把从ZIP到我所期望的名录的零碎碎碎碎fold。 我把“FOLDER”的双倍数中的所有档案都读到,我如何从档案结构中检索?

问题回答

I am not sure what do you mean by particaly? Do you mean do it yourself without of API help?

In the case you don t mind using some opensource library, there is a cool API for that out there called zip4J

It is easy to use and I think there is good feedback about it. See this example:

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

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

如果你想要的档案有密码,你可以尝试:

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

我希望这是有益的。

简明扼要、无图书馆、 Java7+变量:

public static void unzip(InputStream is, Path targetDir) throws IOException {
    targetDir = targetDir.toAbsolutePath();
    try (ZipInputStream zipIn = new ZipInputStream(is)) {
        for (ZipEntry ze; (ze = zipIn.getNextEntry()) != null; ) {
            Path resolvedPath = targetDir.resolve(ze.getName()).normalize();
            if (!resolvedPath.startsWith(targetDir)) {
                // see: https://snyk.io/research/zip-slip-vulnerability
                throw new RuntimeException("Entry with an illegal path: " 
                        + ze.getName());
            }
            if (ze.isDirectory()) {
                Files.createDirectories(resolvedPath);
            } else {
                Files.createDirectories(resolvedPath.getParent());
                Files.copy(zipIn, resolvedPath);
            }
        }
    }
}

两个分支都需要<代码>目录,因为纸面文件并不总是把所有母子目录单独列为条目,但可能只包含空头。

The code addresses the ZIP-slip vulnerability — it fails if some ZIP entry would go outside of the targetDir. Such ZIPs are not created using the usual tools and are very likely hand-crafted to exploit the vulnerability.

这里使用的是Im。 为满足你们的需要而改变布局。

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

public final class ZipUtils {

    private static final int BUFFER_SIZE = 4096;

    public static void extract(ZipInputStream zip, File target) throws IOException {
        try {
            ZipEntry entry;

            while ((entry = zip.getNextEntry()) != null) {
                File file = new File(target, entry.getName());

                if (!file.toPath().normalize().startsWith(target.toPath())) {
                    throw new IOException("Bad zip entry");
                }

                if (entry.isDirectory()) {
                    file.mkdirs();
                    continue;
                }

                byte[] buffer = new byte[BUFFER_SIZE];
                file.getParentFile().mkdirs();
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
                int count;

                while ((count = zip.read(buffer)) != -1) {
                    out.write(buffer, 0, count);
                }

                out.close();
            }
        } finally {
            zip.close();
        }
    }

}

Same can be achieved using Ant Compress library. It will preserve the folder structure.

Maven Depend:-

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

样本代码:-

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

Here s an easy solution which follows more modern conventions. You may want to change the buffer size to be smaller if you re unzipping larger files. This is so you don t keep all of the files info in-memory.

    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))) {

                    int bufferSize = Math.toIntExact(entry.getSize());
                    byte[] buffer = new byte[bufferSize > 0 ? bufferSize : 1];
                    int location;

                    while ((location = zis.read(buffer)) != -1) {
                        bos.write(buffer, 0, location);
                    }
                }
            }
            entry = zis.getNextEntry();
        }
    }
}

这是我用来用多个目录收集齐p文件。 没有使用外部图书馆。

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class UnzipFile
{
  public static void main(String[] args) throws IOException
  {
    String fileZip = "src/main/resources/abcd/abc.zip";
    File destDir = new File("src/main/resources/abcd/abc");

    try (ZipFile file = new ZipFile(fileZip))
    {
      Enumeration<? extends ZipEntry> zipEntries = file.entries();
      while (zipEntries.hasMoreElements())
      {
        ZipEntry zipEntry = zipEntries.nextElement();
        File newFile = new File(destDir, zipEntry.getName());

        //create sub directories
        newFile.getParentFile().mkdirs();

        if (!zipEntry.isDirectory())
        {
          try (FileOutputStream outputStream = new FileOutputStream(newFile))
          {
            BufferedInputStream inputStream = new BufferedInputStream(file.getInputStream(zipEntry));
            while (inputStream.available() > 0)
            {
              outputStream.write(inputStream.read());
            }
            inputStream.close();
          }
        }

      }
    }
  }

}

https://stackoverflow.com/a/59581898/1997376。 very7+变量,但基于流层:

public static void unzip(File zipFile, Path targetDir) throws IOException {
    // Normalize the path to get rid parent folder accesses
    Path targetRoot = targetDir.normalize();
    // Open the zip file as a FileSystem
    try (FileSystem fs = FileSystems.newFileSystem(URI.create("jar:" + zipFile.toURI()), Map.of())) {
        for (Path root : fs.getRootDirectories()) {
            try (Stream<Path> walk = Files.walk(root)) {
                // For each path  in the zip
                walk.forEach(
                    source -> {
                        // Compute the target path of the file in the destination folder
                        Path target = targetRoot.resolve(root.relativize(source).toString()).normalize();
                        if (target.startsWith(targetRoot)) {
                            // Only copy safe files
                            // see: https://snyk.io/research/zip-slip-vulnerability
                            try {
                                if (Files.isDirectory(source)) {
                                    // Create folders
                                    Files.createDirectories(target);
                                } else {
                                    // Copy the file to the destination
                                    Files.copy(source, target);
                                }
                            } catch (IOException e) {
                                throw new UncheckedIOException(e);
                            }
                        }
                    });
            }
        }
    }
}

您应从您的卷宗中查阅所有条目:

Enumeration entries = zipFile.getEntries();

然后从中抽取<代码>Ziptry,检查其是否为名录,并分别制作目录或仅提取文件。

根据pet子的答复,我现在使用的是一只lin子:

fun ZipInputStream.extractTo(target: File) = use { zip ->
    var entry: ZipEntry
    while (zip.nextEntry.also { entry = it ?: return } != null) {
        val file = File(target, entry.name)
        if (entry.isDirectory) {
            file.mkdirs()
        } else {
            file.parentFile.mkdirs()
            zip.copyTo(file.outputStream())
        }
    }
}




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签