ZIP压缩输入/输出流
ZIP压缩管理文件是一种十分典型的文件压缩形式,使用它可以节省储存空间、关于ZIP压缩的I/O流实现,在Java的内置类中提供了非常好用的相关类,ZipOutputStream 与 ZipInputStream 类来实现文件的压缩/解压缩。无论是压缩还是解压还需要用到一个类—ZipEntry类,它为压缩或解压的文件创建条目。
压缩文件
利用ZipOutputStream 类对象,可将文件压缩为.zip文件,压缩文件的过程
ZipOutputStream类的常用方法
方法 | 说明 |
---|---|
putNextEntry(ZipEntry e) | 开始写一个新的ZipEntry,并将流内的位置移至entry所指数据开头 |
write(byte [] b, int off, int len) | 将字节数组写入当前ZIP条目数据 |
finish() | 完成写入ZIP输入流的内容,无须关闭它所配合的OutputStream |
setComment(String comment) | 可设置此ZIP文件的注释文字 |
代码如下:
public class Study2 {
public void zip() {
File f1 = new File("C:\\Users\\逢青\\Desktop\\123");// 压缩的源文件
File f2 = new File("C:\\Users\\逢青\\Desktop\\321.zip");// 压缩包位置
try (FileOutputStream fos = new FileOutputStream(f2); ZipOutputStream zos = new ZipOutputStream(fos)) {
if (f1.isDirectory()) {
// 判断源文件是否为文件夹
for (File f : f1.listFiles()) {
// 遍历文件夹中的文件
addEntry(zos, "", f);//调用创建方法的条目,为遍历的文件创建条目
}
} else {
addEntry(zos, "", f1);//调用创建方法的条目,为文件创建条目
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* @param zos-压缩流
* @param path-文件在压缩包中的路径
* @param f1-压缩的文件
*/
public void addEntry(ZipOutputStream zos, String path, File f1) {
// 创建条目的方法
if (f1.isDirectory()) {
// 判断文件是否为文件夹
for (File file : f1.listFiles()) {
// 遍历文件夹
addEntry(zos, path + f1.getName() + File.separator, file);// 为文件夹下的文件创建条目
}
} else {
byte b[] = new byte[1024];// 创建缓冲区
try (FileInputStream fis = new FileInputStream(f1)) {
int i = -1;
zos.putNextEntry(new ZipEntry(path + f1.getName()));// 在压缩包中添加新条目
//将文件写入压缩包
while ((i = fis.read(b)) != -1) {
zos.write(b,0,i);
zos.flush();//刷新
}
zos.closeEntry();//关闭条目
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Study2 s = new Study2();
s.zip();
}
}
需要注意文件与文件夹是不同的,当压缩的文件里有文件夹时,需要遍历这个文件夹,为文件夹里的文件添加条目。如果是文件就可直接添加条目了。
解压文件
ZipInputStream 类可读取ZIP压缩格式的文件,包括已压缩和未压缩的条目(entry)。
解压文件的过程
ZipInputStream 类的常用方法
方法 | 说明 |
---|---|
read(byte [] b, int off, int len) | 读取目标b数组内off偏移量的位子,长度是len字节 |
available() | 判断是否已读完目前entry所指定的数据。已读完返回0,未读完返回1 |
closeEntry() | 关闭当前ZIP条目并定位流以读取下一个条目 |
skip(long n) | 跳过当前ZIP条目的指定字节数 |
getNextEntry() | 读取下一个ZipEntry,并将流内的位置移至该entry所指数据的开头 |
createZipEntry(String name) | 以指定的name参数新建一个ZipEntry对象 |
代码如下:
public class Study {
static void decompression() {
File f1 = new File("C:\\Users\\逢青\\Desktop\\123");//目标文件夹
File f2 = new File("C:\\Users\\逢青\\Desktop\\321.zip");//解压的源文件
byte b[] = new byte[1024];//缓冲区
ZipEntry zn = null;
try(FileInputStream fis = new FileInputStream(f2);ZipInputStream zis = new ZipInputStream(fis)) {
while(true) {
zn = zis.getNextEntry();//获取条目
if(zn == null) {
//判断是否为空,空则结束
break;
}
if(zn.isDirectory()) {
//判断是否为文件夹,是则跳过
continue;
}
File f = new File(f1,zn.getName());
if(!f.getParentFile().exists()) {
//判断目标文件夹是否存在
f.getParentFile().mkdirs();//创建目标文件夹
}
int i = -1;
FileOutputStream fos = new FileOutputStream(f);
while((i = zis.read(b)) != -1) {
fos.write(b, 0, i);
fos.flush();
}
fos.close();
zis.closeEntry();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
decompression();
}
}