一、解压缩流/压缩流
1.2 解压缩流
1.2.1 什么是解压缩流?
解压缩流是Java I/O系统中专门用于读取压缩文件的流,它能将压缩后的数据恢复为原始格式。简单来说,就是把.zip、.gz这些压缩文件"打开"的工具。
1.2.2 主要解压缩类
Java提供了两种主要的解压缩流:
| 类名 | 用途 | 压缩格式 |
|---|---|---|
ZipInputStream | 读取ZIP格式的压缩文件 | ZIP (支持多文件和目录) |
GZIPInputStream | 读取GZIP格式的压缩文件 | GZIP (主要用于单个文件) |
💡小贴士:ZIP更常用,因为它可以打包多个文件和目录,而GZIP通常用于单个文件。
1.2.3 解压缩的核心步骤
1. 基本解压流程
// 1. 创建文件输入流 FileInputStream fis = new FileInputStream("archive.zip"); // 2. 创建ZIP解压流 ZipInputStream zis = new ZipInputStream(fis); // 3. 读取每个条目 ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { // 4. 处理目录或文件 if (entry.isDirectory()) { // 创建目录 } else { // 创建文件并写入数据 } // 5. 关闭当前条目 zis.closeEntry(); } // 6. 关闭解压流 zis.close();2. 关键方法详解
getNextEntry():获取下一个条目(文件或目录),返回ZipEntry对象isDirectory():判断当前条目是否是目录getName():获取条目的名称(包括路径)closeEntry():关闭当前条目,准备读取下一个
package com.lkbhua.IO2.ZipStreamDemo; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class demo1 { public static void main(String[] args) throws IOException { // 1、创建一个File去表示要解压的压缩包 File src = new File("C:\\Users\\27116\\Desktop\\test.zip"); // 2、创建一个File去表示要解压到的目录 File dest = new File("C:\\Users\\27116\\Desktop\\bbb"); // 3、调用方法进行解压 unZip(src, dest); } // 定义一个方法用来解压 public static void unZip(File src, File dest) throws IOException { // 解压的本质: 把压缩包里面的每一个文件或者文件夹去读取出来,按照层级去拷贝到目的地当中 // 创建一个解压缩流用来读取压缩包中的数据 ZipInputStream zis = new ZipInputStream(new FileInputStream(src)); // 要先获取到压缩包里面的每一个文件或者文件夹 // 表示当前在压缩包中获取到的文件或者文件夹 ZipEntry entry; while((entry = zis.getNextEntry()) != null){ if(entry.isDirectory()){ // 文件夹:需要在目的地dest处创建一个同样的文件夹 File file = new File(dest, entry.toString()); file.mkdirs(); }else{ // 文件: 需要读取到压缩包中的文件,并把他存放到目的地dest文件夹中(按照层级目录) FileOutputStream fos = new FileOutputStream(new File(dest, entry.toString())); int b; while((b = zis.read()) != -1){ // 创建一个文件输出流,把数据写入到目的地的文件中 fos.write(b); } fos.close(); // 表示在压缩包中的一个文件处理完毕了 zis.closeEntry(); } } // 关闭输入流 zis.close(); } }1.3 压缩流
1.3.1 什么是压缩流?
压缩流不是一种独立的流,而是一组基于装饰器模式的过滤流(处理流)。它们"装饰"在基本的字节流之上,在写入数据时自动进行压缩,在读取数据时自动进行解压缩。
💡简单理解:
就像给文件穿上一件"压缩外套",传输时体积变小,接收时自动脱掉外套恢复原样。
1.3.2 为什么需要压缩流?
- 节省空间:压缩后文件体积变小
- 节省带宽:网络传输时更快
- 方便打包:ZIP可以打包多个文件和目录
1.3.3 Java压缩流的核心类
Java处理压缩文件主要依赖于java.util.zip包中的几个核心类:
| 类名 | 作用 | 压缩格式 | 适用场景 |
|---|---|---|---|
ZipOutputStream | 创建ZIP压缩文件 | ZIP | 打包多个文件和目录 |
ZipInputStream | 读取ZIP压缩文件 | ZIP | 解压ZIP文件 |
GZIPOutputStream | 创建GZIP压缩文件 | GZIP | 单个文件压缩 |
GZIPInputStream | 读取GZIP压缩文件 | GZIP | 解压GZIP文件 |
ZipEntry | 表示ZIP文件中的一个条目 | - | 代表文件或目录的元数据 |
💡小贴士:ZIP更常用,因为它可以打包多个文件和目录;GZIP通常用于单个文件。
1.3.4ZIP压缩流实战:创建压缩文件
1. 基本流程
// 1. 创建文件输出流 FileOutputStream fos = new FileOutputStream("archive.zip"); // 2. 创建ZIP压缩流 ZipOutputStream zos = new ZipOutputStream(fos); // 3. 为每个文件创建ZipEntry ZipEntry entry = new ZipEntry("file.txt"); zos.putNextEntry(entry); // 4. 写入文件内容 FileInputStream fis = new FileInputStream("file.txt"); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zos.write(buffer, 0, len); } // 5. 关闭当前条目 zos.closeEntry(); // 6. 关闭所有资源 zos.close();单个文件:
package com.lkbhua.IO2.ZipStreamDemo; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class demo2 { public static void main(String[] args) { /* 压缩流——单个文件 */ // 1、创建一个File对象表示要压缩的文件 File src = new File("D:\\a.txt"); // 2、创建一个File对象表示压缩包的位置 File dest = new File("D:\\"); // 3、调用方法用来压缩 } /* * 压缩方法 * 参数:src要压缩的文件 dest压缩包的位置 * 返回值:无 * */ public static void toZip(File src, File dest) throws IOException { // 1、创建压缩流关联压缩包 ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest, "a.zip"))); // 2、创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹 ZipEntry entry = new ZipEntry("a.txt"); // 3、把ZipEntry对象写入到压缩流=包中 zos.putNextEntry(entry); // 4、把文件内的数据写入到压缩包中 FileInputStream fis = new FileInputStream(src); int b; while ((b = fis.read()) != -1) { zos.write(b); } fis.close(); zos.close(); } }文件夹:
package com.lkbhua.IO2.ZipStreamDemo; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class demo3 { public static void main(String[] args) throws IOException { /* 压缩——压缩多级文件 */ // 1、创建File对象表示要压缩的文件夹 File src = new File("C:\\Users\\27116\\Desktop\\bbb"); // 2、创建File对象表示压缩包放在哪里(压缩包的父级路径) File destParent = src.getParentFile(); // 3、创建File对象表示压缩包的路径 File dest = new File(destParent, src.getAbsolutePath()+".zip"); // 4、创建压缩流关联压缩包 ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest)); // 5、获取src里面的每一个文件,编程zipEntry,并添加到压缩包中 toZip(src, zos, src.getName()); // 6、释放压缩流 zos.close(); } /* * 压缩多级文件 * src:要压缩的文件夹 * zos:压缩包存放的位置 * name:压缩包内部的路径(名称) * */ public static void toZip(File src, ZipOutputStream zos,String name) throws IOException { // 1、进入src文件夹 File[] files = src.listFiles(); // 2、遍历数组 for (File file : files) { if(file.isFile()){ // 3、判断 = 文件,变成zipEntry对象放到压缩包当中 ZipEntry entry = new ZipEntry(name+"\\"+file.getName()); zos.putNextEntry(entry); // 读取文件中的数据,写到压缩包 FileInputStream fis = new FileInputStream(file); int b; while ((b = fis.read()) != -1) { zos.write(b); } fis.close(); zos.closeEntry(); }else{ // 4、判断 = 文件夹,递归 toZip(file, zos, name+"\\"+file.getName()); } } } }