一、Zip文件的解析
在解压zip文件时,有一类专门的输入流ZipInputStream,继承自FilterInputStream,用来实现Zip文件的读取,这类输入流是完成特定功能的输入流,采用java设计模式中的装饰器模式,要配合InputStream类型的输入流一起使用,完成zip文件的解析。
在解析zip文件的时候,第一步要先建立解压缩后的目录,然后获取zip文件的名称,根据名称确定解压缩后的文件目录,然后创建目录。
第二步要先遍历zip文件中的每一个子文件,每一个子文件都是ZipEntry类型的对象,使用getNextEntry()方法把每一个子文件读取出来,然后获取每个子文件的名称,确定解压缩以后的文件路径,创建每一个文件的输入流,使用BufferedOutputStream批量读取子文件的内容,循环调用上述步骤,直到读取完毕。
实现代码如下:
package com.yx.demo;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
*
* 解压缩zip文件
*
*/
public class Demo01 {
public static void main(String[] args) {
//要进行解压缩的文件
File zipFile = new File("d:\\test\\1-201023201325.zip");
//1创建解压缩目录
//获取zip文件名称
String zipFileName = zipFile.getName();
//根据zip文件名称,提取压缩目录的名称
String targetDirName = zipFileName.substring(0,zipFileName.indexOf("."));
//创建压缩目录
File targetDir = new File(zipFile.getParent() + "\\" + targetDirName);
if(!targetDir.exists()) {
targetDir.mkdir(); //创建目录
}
//2.解析读取zip文件
try (
ZipInputStream in = new ZipInputStream(new FileInputStream(zipFile),Charset.forName("gbk"))) {
//遍历Zip文件中每个子文件
ZipEntry zipEntry = null;
while((zipEntry = in.getNextEntry())!= null) {
//获取zip压缩包中的子文件名称
String zipEntryFileName = zipEntry.getName();
String zipFilePath = targetDir.getPath() + "\\" + zipEntryFileName;
//创建该文件的输出流
try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(zipFilePath));){
//读取该子文件的字节内容
byte[] buff = new byte[1024];
int len = -1;
while((len = in.read(buff))!= -1) {
bos.write(buff, 0, len);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、生成zip文件
ZipOutputStream是zip文件的指定输出流,是FilterOutputStream的子类,它的作用是可以直接将文件直接写入zip包,同样采用装饰器模式,配合FileOutputStream使用。
生成zip文件的第一步是先获取原文件的原始目录,根据原目录生成同一级目录下压缩后的压缩文件目录,第二步创建File类型的数组调用listFiles()方法t通过foreach循环获取所有子文件,第三步创建zipEntry类型的对象,调用 ZipOutputStream的putNextEntry()方法获取子文件的内容,使用write()方法配合Files工具类readAllBytes()方法将原子文件的内容全部写入zip压缩包,全部写入以后,调用closeEntry()方法关闭zipEntry。
实现代码如下:
package com.yx.demo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
*
* 将指定文件写入zip文件
*
*/
public class Demo02 {
public static void main(String[] args) {
//原始目录
File rootDir = new File("d:\\test\\img");
//将原始目录中的文件,“写入”zip压缩文件
try ( ZipOutputStream out = new ZipOutputStream(new FileOutputStream(rootDir.getParent() + "\\" +rootDir.getName() + ".zip"))) {
//获取并遍历原始目录下的子文件夹
File[] files = rootDir.listFiles();
for(File f : files) {
//创建一个zipEntry
out.putNextEntry(new ZipEntry(f.getName()));
//将原文件的字节内容,写入zip压缩包
out.write(Files.readAllBytes(f.toPath()));
//结束当前zipEntry
out.closeEntry();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}