本文介绍如何使用内置的 Java API 提取压缩的 zip 存档中的文件和目录。
java.util.zip 提供了以下类用于提取 zip 包中的文件和目录:
ZipInputStream – 这是主类,用于读取 zip 文件并提取里面的文件和目录(实体)。这个类有以下有用的方法:
-调用 ZipInputStream(FileInputStream) 构造函数可以读取 zip 文件
-调用 getNextEntry() 方法读取 zip 包内部的实体。
-调用 read(byte) 方法读取当前实体的二进制数据。
-调用 closeEntry() 方法关闭当前实体。
-调用 close() 方法关闭当前 zip 文件
ZipEntry – 这个类用于表示 zip 文件中的实体,每个文件或目录都对应一个 ZipEntry 对象。它的 getName() 方法返回当前实体的路径,返回的路径格式如下:
folder_1/subfolder_1/subfolder_2/…/subfolder_n/file.ext
基于 ZipEntry 返回的路径,我们可以重新构造目录结构
另外调用 BufferedOutputStream 类的 write(byte[] bytes, int offset, int length) 方法可以将当前的 ZipEntry 内容写出到硬盘,
下面是一个完整的示例 UnzipUtility.java :
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;
/**
* This utility extracts files and directories of a standard zip file to
* a destination directory.
*/
public class UnzipUtility {
/**
* Size of the buffer to read/write data
*/
private static final int BUFFER_SIZE = 4096;
/**
* Extracts a zip file specified by the zipFilePath to a directory specified by
* destDirectory (will be created if does not exists)
* @param zipFilePath
* @param destDirectory
* @throws IOException
*/
public void unzip(String zipFilePath, String destDirectory) throws IOException {
File destDir = new File(destDirectory);
if (!destDir.exists()) {
destDir.mkdir();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry entry = zipIn.getNextEntry();
// iterates over entries in the zip file
while (entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
if (!entry.isDirectory()) {
// if the entry is a file, extracts it
extractFile(zipIn, filePath);
} else {
// if the entry is a directory, make the directory
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
/**
* Extracts a zip entry (file entry)
* @param zipIn
* @param filePath
* @throws IOException
*/
private void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
bos.close();
}
}
UnzipUtility 类的有一个公共方法可以提取 zip 包中的文件和目录:
unzip(String zipFilePath, String destDirectory) – 将 zipFilePath 指定的 zip 文件的内容提取到 destDirectory 指定的目录。
下面是测试类 UnzipUtilityTest.java :
public class UnzipUtilityTest {
public static void main(String[] args) {
String zipFilePath = "e:/Test/MyPics.zip";
String destDirectory = "f:/Pics";
UnzipUtility unzipper = new UnzipUtility();
try {
unzipper.unzip(zipFilePath, destDirectory);
} catch (Exception ex) {
// some errors occurred
ex.printStackTrace();
}
}
}