Java – IO流 – 解压缩流
简介
解压缩流,顾名思意,就是用于压缩和解压数据用的IO流操作方法,它能压缩和解压Zip压缩文件的功能,目前只支持Zip.
ZipOutputStream 压缩流
ZipOutputStream
可以对文件进行Zip压缩。
构造函数
// 对文件或目录创建压缩流
public ZipOutputStream(OutputStream out);
// 对文件或目录进行自定义字符集压缩流
public ZipOutputStream(OutputStream out, Charset charset)
创建对象
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("path"));
创建对象我们可以看作新建了一个空的zip压缩文件
ZipEntry 压缩文件对象
对于 ZipOutputStream
压缩流而言,压缩包中的每一个文件夹或文件,都视作一个对象,被称为 ZipEntry
对象。
要如何获得 ZipEntry
对象,我们直接 new
创建一个 ZipEntry
对象就可以,可以看作是一个空的文件
// 构造函数中的参数 name 指的是压缩包文件里的文件名
ZipEntry z = new ZipEntry(String name);
这里要注意:ZipEntry
对象中的name
,除了表示压缩包中的文件名外,它还包含了文件的目录结构,也就是说 name
可以为 "dir1\\dir2\\file
",在存入压缩包时,ZipOutputStream
会自动按照name
的目录结构创建文件夹。
创建完ZipEntry
对象后,需要往 zos 对象中存入 ZipEntry
对象。可以看作是把一个空文件存入 zip 压缩包中。
// 把 压缩文件存入zip压缩包中
zos.putNextEntry(z);
注意:
1.ZipEntry 对象的 name
可以包含目录结构,但基于相对路径,如【dir1\\dir2\\file】
2.ZipEntry 对象可以通过 toString()
方法获得该文件的文件名或结构
3.ZipEntry 对象还包含这个压缩文件的众多属性,可以参考
4.ZipEntry 是一个zip对象流,使用完后应当关闭当前压缩文件的对象流,但不是 zipEntry.close()
, 而是通过 zos(zip对象)去关闭
zos.closeEntry();
对数据进行压缩写入操作
通过使用 FileInputStream
对像对文件进行读取,并使用 zos.write()
方法写入数据到压缩包文件中。
FileInputStream f = new FileInputStream(src);
byte[] data = new byte[1024000];
int len;
// 读取文件
while ((len = f.read(data)) != -1) {
// zip 包中写入这个文件的数据
zip.write(data, 0, len);
}
示例:压缩文件
需求:能对单个文件或文件夹进行zip压缩处理
public static void tozip(File dest, File src, String zipName) throws IOException {
// 不管是文件还是文件夹,开始的时候都要新建一个zip包
ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(new File(dest, zipName + ".zip")));
if (src.isFile()) {
// 当要压缩的是一个文件时
toZipFile(src, zip);
} else {
// 当要压缩的是一个文件夹时
tozipDir(src, zip, src.getName());
}
zip.close();
}
private static void toZipFile(File src, ZipOutputStream zip) throws IOException {
// 创建一个 ZipEntry 对象,就是相当于创建一个压缩文件对象
ZipEntry z = new ZipEntry(src.getName());
// 把压缩文件存到压缩包中
zip.putNextEntry(z);
// 取得文件读取权
FileInputStream f = new FileInputStream(src);
byte[] data = new byte[1024000];
int len;
// 读取文件
while ((len = f.read(data)) != -1) {
// zip 包中写入这个文件的数据
zip.write(data, 0, len);
}
// 写完关闭io流
zip.closeEntry();
f.close();
}
public static void tozipDir(File src, ZipOutputStream zip, String parentDir) throws IOException {
// 先遍历文件夹中的文件
File[] files = src.listFiles();
for (File file : files) {
if (file.isFile()) {
// 如果是文件, 直接创建一个 ZipEntry ,每一个文件可以看作是一个ZipEntry对象
// 注意,这里的 name 是可以包含压缩文件目录的
/*
* 这里的目录名比较难理解
* 因为ZipEntry对象中包含了目录路径,如果使用递归的话,这里的name设置是考虑到多层文件夹嵌套问题
* 其目录递归后的效果如下
* Dirxx
* Dirxx\\Dir2
* Dirxx\\Dir2\\Dir3
* ...
* 如此类推,使用了parentDir参数传入上一次的父级路径
* */
ZipEntry z = new ZipEntry(parentDir + "\\" + file.getName());
zip.putNextEntry(z);
FileInputStream f = new FileInputStream(file);
byte[] data = new byte[1024000];
int len;
while ((len = f.read(data)) != -1) {
zip.write(data, 0, len);
}
// 读写完后关闭ZipEntry对象的读写流
zip.closeEntry();
// 关闭文件流
f.close();
} else {
// 如果是文件夹
/*
* 这里是一个重点,
* 因为使用了递归思想,所以需要传入上一级的相对目录,提供给 ZipEntry 的 name 使用
* 考虑到多级目录嵌套问题
* */
tozipDir(file, zip, parentDir + "\\" + file.getName());
}
}
}
ZipInputStream 解压流
ZipOutputStream 可以对 Zip 文件进行解压。
构造函数
// 对Zip文件进行解压流
public ZipInputStream(InputStream in);
// 对Zip文件进行自定义字符集解压流
public ZipInputStream(InputStream in, Charset charset)
创建解压对象
ZipInputStream zis = new ZipInputStream(new FileInputStream("path"));
ZipEntry 压缩文件对象
对于 ZipInputStream 解压流而言,压缩包中的每一个文件夹或文件,都视作一个对象,被称为 ZipEntry 对象。
要如何获得 ZipEntry 对象,使用 ZipInputStream 对象的 getNextEntry() 方法,可获得。
// 通过调用 ZipInputStream 实例对象,取得压缩文件对象 ZipEntry
ZipEntry nextEntry = zis.getNextEntry();
每次执行 getNextEntry() 方法,便会输出一个压缩包里的文件结构,我们可以通过循环遍历出压缩文件中的所有文件名和结构
ZipInputStream zis = new ZipInputStream(new FileInputStream("path"));
ZipEntry zipEntry;
// 通过 while 循环,遍历所有压缩包中的文件结构
while ((zipEntry = zis.getNextEntry()) != null) {
System.out.println(zipEntry.toString());
}
注意:
1.如果遍历完成,依然调用 getNextEntry() 方法,会返回 null
2.zipEntry 对象可以通过 toString() 方法获得该文件的文件名或结构
3.zipEntry 对象还包含这个压缩文件的众多属性,可以参考
4.zipEntry 是一个zip对象流,使用完后应当关闭当前压缩文件的对象流,但不是 zipEntry.close() , 而是通过 zis(zip对象)去关闭
zis.closeEntry();
isDirectory()方法
ZipEntry 对象中,没有 isFile() 的方法,只有 isDirectory() 方法,我们只能通过判断是否是文件夹,来判断区分文件与文件夹,并作对应的操作
示例:解压Zip包
需求:解压一个Zip压缩包到指定位置。
public static void unzip(File dest, File src) throws IOException {
// 取得一个压缩包的地址,并创建一个解压流对象
ZipInputStream zip = new ZipInputStream(new FileInputStream(src));
ZipEntry zipEntry;
while ((zipEntry = zip.getNextEntry()) != null) {
if (zipEntry.isDirectory()) {
// 如果是文件夹,那么就在指定的位置基础下创建一个文件夹
File f = new File(dest, zipEntry.toString());
f.mkdirs();
} else {
// 如果是文件,那么就使用 zip 对象方法,写出数据到指定地方
FileOutputStream fos = new FileOutputStream(new File(dest, zipEntry.toString()));
byte[] data = new byte[1024000];
int len;
while ((len = zip.read(data)) != -1) {
// 对文件进行写出
fos.write(data, 0, len);
}
// 对文件输出流进行关闭流
fos.close();
// 对 ZipEntry 对象读写完之后,应当关闭 ZipEntry 读写流
zip.closeEntry();
}
}
// 对所有文件解压完后,应当关闭 zip 解压流对象
zip.close();
}
共有 0 条评论