准备
有压缩文件:
zxm@zxm-pc:~$ unzip -t test.zip
Archive: test.zip
testing: a.txt OK
testing: b.txt OK
testing: c/ OK
testing: c/c.txt OK
testing: d.zip OK
No errors detected in compressed data of test.zip.
一、解压 zip
可使用 ZipFile 或 ZipInputStream 解压 zip 文件
@Test
public void testUnzip1() throws Exception {
String targetRoot = "/home/zxm/test";
ZipFile zipFile = new ZipFile(new File("/home/zxm/test.zip"));
System.out.println("file count:" + zipFile.size());
Enumeration enumeration = zipFile.entries();
while (enumeration.hasMoreElements()) {
ZipEntry entry = (ZipEntry) enumeration.nextElement();
String name = entry.getName();
System.out.println("name:" + name);
File outFile = new File(targetRoot + "/" + name);
if (entry.isDirectory()) {
// 如果是目录,则创建目录
if (!outFile.exists()) {
outFile.mkdirs();
}
continue;
}
BufferedInputStream inputStream = new BufferedInputStream(zipFile.getInputStream(entry));
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outFile));
int len;
byte[] buffer = new byte[1024];
while ((len = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
outputStream.close();
inputStream.close();
}
zipFile.close();
}
@Test
public void testUnzip2() throws Exception {
String targetRoot = "/home/zxm/test";
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("/home/zxm/test.zip"));
ZipEntry zipEntry = null;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
String name = zipEntry.getName();
System.out.println("name:" + name);
File outFile = new File(targetRoot + "/" + name);
if (name.endsWith("/")) {
// 如果是目录,则创建目录
if (!outFile.exists()) {
outFile.mkdir();
}
continue;
}
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outFile));
int len;
byte[] buffer = new byte[1024];
while ((len = zipInputStream.read(buffer, 0, buffer.length)) > 0) {
outputStream.write(buffer, 0, len);
}
outputStream.close();
}
zipInputStream.close();
}
二、读取 zip
可使用 ZipFile 或 ZipInputStream 读取 zip。若读取嵌套的 zip,可把嵌套的 zip 写入临时文件,再从嵌套的 zip 读取内部文件内容
@Test
public void testReadZip1() throws Exception {
ZipFile zipFile = new ZipFile(new File("/home/zxm/test.zip"));
System.out.println("file count:" + zipFile.size());
Enumeration enumeration = zipFile.entries();
while (enumeration.hasMoreElements()) {
ZipEntry entry = (ZipEntry) enumeration.nextElement();
String name = entry.getName();
System.out.println("name:" + name);
if (name.endsWith(".zip")) {
continue;
}
BufferedReader br = new BufferedReader(new InputStreamReader(zipFile.getInputStream(entry)));
String line;
StringBuilder builder = new StringBuilder();
while ((line = br.readLine()) != null) {
builder.append(line);
}
System.out.println("content: " + builder);
}
zipFile.close();
}
@Test
public void testReadZip2() throws Exception {
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("/home/zxm/test.zip"));
ZipEntry zipEntry = null;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
String name = zipEntry.getName();
System.out.println("name:" + name);
if (name.endsWith(".zip")) {
continue;
}
BufferedReader br = new BufferedReader(new InputStreamReader(zipInputStream));
String line;
StringBuilder builder = new StringBuilder();
while ((line = br.readLine()) != null) {
builder.append(line);
}
System.out.println("content: " + builder);
}
zipInputStream.closeEntry();
}
读取指定的单个文件。若读取嵌套的 zip 中的单个文件,先把嵌套的 zip 中写入临时文件,再从临时的 zip 文件,读取指定的单个文件
@Test
public void testReadZipOneFile() throws Exception {
ZipFile zipFile = new ZipFile(new File("/home/zxm/test.zip"));
InputStream inputStream = zipFile.getInputStream(zipFile.getEntry("c/c.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuilder builder = new StringBuilder();
while ((line = br.readLine()) != null) {
builder.append(line);
}
System.out.println("content: " + builder);
}
@Test
public void testReadInnerZipOneFile() throws Exception {
String outerZipFilePath = "/home/zxm/test.zip";
String innerZipFileName = "d.zip";
String targetFileName = "d.txt";
ZipFile outerZipFile = new ZipFile(outerZipFilePath);
ZipEntry innerZipEntry = outerZipFile.getEntry(innerZipFileName);
// 创建临时文件
File tempFile = File.createTempFile("inner_zip_", ".zip");
FileOutputStream tempOs = new FileOutputStream(tempFile);
InputStream tempIs = outerZipFile.getInputStream(innerZipEntry);
byte[] buffer = new byte[1024];
int len;
while ((len = tempIs.read(buffer)) > 0) {
tempOs.write(buffer, 0, len);
}
tempOs.close();
tempIs.close();
// 读取内部zip的一个文件内容
ZipFile innerZipFile = new ZipFile(tempFile);
InputStream inputStream = innerZipFile.getInputStream(innerZipFile.getEntry(targetFileName));
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuilder builder = new StringBuilder();
while ((line = br.readLine()) != null) {
builder.append(line);
}
System.out.println("content: " + builder);
}
三、压缩 zip
把多个文件,打包进 zip
@Test
public void testZip() throws Exception {
Map<String, File> map = new HashMap<>();
map.put("a.txt", new File("/home/zxm/test/a.txt"));
map.put("b.txt", new File("/home/zxm/test/b.txt"));
map.put("c/c.txt", new File("/home/zxm/test/c/c.txt"));
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream("/home/zxm/test1.zip"));
for (Map.Entry<String, File> entry : map.entrySet()) {
String name = entry.getKey();
File file = entry.getValue();
ZipEntry zipEntry = new ZipEntry(name);
zipOutputStream.putNextEntry(zipEntry);
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
int len;
byte[] buffer = new byte[1024];
while ((len = inputStream.read(buffer)) > 0) {
zipOutputStream.write(buffer, 0, len);
}
inputStream.close();
}
zipOutputStream.closeEntry();
zipOutputStream.close();
}