Java的I/O流——ZIP压缩输入/输出流

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();
	}
}

猜你喜欢

转载自blog.csdn.net/javanofa/article/details/104592206