12.13 压缩流

  • 12.13.1 ZIP压缩输入/输出流简介
  • 12.13.2 ZipOutputStream 类
  • 【例12.61】压缩test.zip文件
  • 【例12.62】压缩一个文件夹
  • 12.13.3 ZipFile 类
  • 【例12.63】实例化ZipFile类对象
  • 【例12.64】解压缩文件
  • 12.13.4 ZiplnputStream 类
  • 【例 12.65】取得 mldn.zip 中的一个 ZipEntry
  • 【例12.66】解压缩mldndir.zip文件


在 日 常 的 使 用 中 经 常 会 使 用 到 像 W i n R A RW i n Z I P 等 压 缩 文 件 , 通 过 这 些 软 件 可 以 把 一 个 很 大 的 文 件 进 行 压 缩 以 便 传 输 , 如 图 1 2 - 2 0 所 示 。 在 J a v a 中 为 了 减 少 传 输 时 的 数 据 量 也 提 供 了专门的压缩流,可以将文件或文件夹压缩成ZIP、JAR、GZIP等文件形式。

12.13.1 ZIP压缩输入/输出流简介

ZIP是一种较为常见的压缩形式,在Java中要想实现ZIP的压缩需要导入java.util.zip包, 可以使用此包中的 ZipFile、ZipOutputStream,ZipInputStream, ZipEntry 几个类完成操作.

java 压缩 io速度慢 java 压缩流_System


java 压缩 io速度慢 java 压缩流_输出流_02


表12-19 ZipEntry类的常用方法

序 号         方 法       类 型         描 述 
1 public ZipEntry(String name) 构造 创建对象并指定要创建的ZipEntry名称
2 public boolean isDirectory() 普通 判断此ZipEntry是否是目录

压缩的输入/输出类是定义在java.utii.zip包中。压缩的输入/输出流也属于InputStreamOutputStream的子类,但是却没有定义在java.io包中而是以一种工具类的形式提供的,在操作的时候仍然需要使用java.io包的支持。

12.13.2 ZipOutputStream 类

如果要想完成一个文件或文件夹的压缩,要使用ZipOutputStream类完成,ZipOutputStream 是OutputStream的子类,常用操作方法如表12-20所示。

表12-20 ZipOutputStream类的常用方法

序 号 		方 法		 类 型		 描 述 
1 public ZipOutputStream(OutputStream out) 构造 创建新的ZIP输出流
2 public void putNextEntry(ZipEntry e) throws IOException 普通 设置每一个ZipEntry对象
3 public void setComment(String comment) 普通 设置ZIP文件的注释

【例12.61】压缩test.zip文件

package jiaqi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class demo429_1
{
	public static void main(String[] args)throws Exception
	{
		//要压缩的文件
		File file = new File("d:" + File.separator + "test.txt");
		//定义压缩文件名
		File zipFile = new File("d:" + File.separator + "test.zip");
		
		//定义文件输入流
		InputStream input = new FileInputStream(file);
		
		//定义ZIP输出流
		ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(zipFile));
		
		//实体起名
		zipout.putNextEntry(new ZipEntry(file.getName()));
		
		//设注释
		zipout.setComment("www.mycomputer.top");
		
		
		//读取+输出
		int temp = 0;
		while((temp = input.read())!=-1)
		{
			zipout.write(temp);
		}
		
		//关闭
		input.close();
		zipout.close();	
		
	}
}

结果:

java 压缩 io速度慢 java 压缩流_System_03

java 压缩 io速度慢 java 压缩流_System_04

【例12.62】压缩一个文件夹

java 压缩 io速度慢 java 压缩流_java_05


针对的是:文件加下全部是具体文件。没有嵌套的文件加

package jiaqi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class demo430_1
{

	public static void main(String[] args) throws Exception
	{
		File file = new File("d:" + File.separator + "mldn");
		File zipfile = new File("d:" + File.separator + "mldndir.zip");
		
		InputStream input = null;
		ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(zipfile));
		
		//注释
		zipout.setComment("www.mycomputer.top");
		
		//判断是否文件夹
		if(file.isDirectory())
		{
			//完全路径
			File lists[] = file.listFiles();
			for(int i = 0; i < lists.length ; i++)
			{
				//输入流一定是具体文件(.txt)
				input = new FileInputStream(lists[i]);
				
				//设置名字     设置每一级的zipentry
				zipout.putNextEntry(new ZipEntry(file.getName() + File.separator +lists[i].getName()));
				
				//读入+写出
				int temp = 0 ;
				while ((temp = input.read())!=-1)
				{
					zipout.write(temp);
				}
				
			}
		}
		
		zipout.close();
		input.close();
		
	}

}
package jiaqi;

import java.io.File;
import java.util.zip.ZipFile;

public class demo432_1 {

	public static void main(String[] args) throws Exception
	{
		// TODO 自动生成的方法存根
		File zipfile = new File("d:" + File.separator + "mldndir.zip");
		ZipFile zf = new ZipFile(zipfile);
		
		System.out.println(zf.getName());
		
	}

}

12.13.3 ZipFile 类

在 J a v a 中 , 每 一 个 压 缩 文 件 都 可 以 使 用 Z i p F i l e 表 示 , 还 可 以 使 用 Z i p F i l e 根 据 压 缩 后 的 文 件 名 称 找 到 每 一 个 压 缩 文 件 中 的 Z i p E n t r y 并 将 其 进 行 解 压 缩 操 作 , Z i p F i l e 类 的 常 用 方 法 如表12-21所示
表12-21 ZipFile类的常用方法

序 号 	方 法 		类 型		 描 述 
1 public ZipFile(File file) throws ZipException, IOException 构造 根据File类实例化ZipFile对象
2 public ZipEntry getEntry(String name) 普通 根裾名称找到其对应的ZipEntry 
3 public InputStream getInputStream(ZipEntry entry) throws IOException 普通 根据 ZipEntry 取得 InputStream 实例
4 public String getName() 普通 得到压缩文件的路径名称

【例12.63】实例化ZipFile类对象

package jiaqi;

import java.io.File;
import java.util.zip.ZipFile;

public class demo432_1 {

	public static void main(String[] args) throws Exception
	{
		// TODO 自动生成的方法存根
		File zipfile = new File("d:" + File.separator + "mldndir.zip");
		ZipFile zf = new ZipFile(zipfile);
		System.out.println(zf.getName());	
	}
}

【例12.64】解压缩文件

package jiaqi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

public class demo432_2 
{
	//1.获得输入流-->ZipFile的对象zipfile-->获得entry-->              
	//2.获得输出流-->具体解压的文件名(路径)

	public static void main(String[] args) throws Exception 
	{
		//压缩的文件
		File file = new File("d:" + File.separator + "mldn.zip");
		
		//解压的文件名称
		File outfile =new File("d:" + File.separator + "mldn.txt");
		
		//压缩包
		ZipFile zipfile = new ZipFile(file);
		
		//得到一个压缩实体
		ZipEntry en = zipfile.getEntry("mldn.txt");
		
		//得到实体的输入流
		InputStream input = zipfile.getInputStream(en);
		
		//输出流
		OutputStream out = new FileOutputStream(outfile);
		
		int temp = 0;
		while ((temp = input.read()) != -1)
		{
			out.write(temp);
		}
		
		input.close();
		out.close();
	}
}

上 面 程 序 是 将 D 盘 中 m l d n . z i p 中 的 文 件 解 压 缩 到 m l d n _ u n z i p . t x t 文 件 中 。 程 序 首 先 通 过 getEntry()方法根据名称取得一个压缩的ZipEntry,之后通过InputStream取得此ZipEntry的输入 流,并通过循环的方式将全部的内容通过输出流输出。
但 是 , 上 面 的 程 序 只 适 合 压 缩 文 件 中 存 在 一 个 Z i p E n t r y 的 情 况 , 如 果 一 个 压 缩 文 件 中 存 在 文 件 夹 或 者 多 个 Z i p E n t r y 就 无 法 使 用 了 , 如 果 要 操 作 更 加 复 杂 的 压 缩 文 件 , 就 必 须 结 合 ZiplnputStream 类完成。

12.13.4 ZiplnputStream 类

ZiplnputStreamInputStream的子类,通过此类,可以方便地读取ZIP格式的压缩文件,此类的常用方法如表12-22所示。
表12-22 ZiplnputStream类的常用方法

序 号 方 法 类 型 描 述 
1 public ZipInputStream(InputStream in) 构造 实例化ipInputStream对象
2 public ZipEntry getNextEntry() throws IOException 普通 取得下一个ZipEntry

使用ZiplnputStream可以像ZipFile 一样,也可以取得ZIP压缩文件中的每一个ZipEntry。

【例 12.65】取得 mldn.zip 中的一个 ZipEntry

package jiaqi;

import java.io.File;
import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class demo433_1 {

	public static void main(String[] args) throws Exception
	{
		File zipfile = new File("d:"+ File.separator +"mldn.zip");
		ZipInputStream zis = new ZipInputStream(new FileInputStream(zipfile));
		
		//从ZIP压缩包中获得实体
		ZipEntry entry = zis.getNextEntry();
//		ZipEntry entry1 = zis.getNextEntry();
//		ZipEntry entry2 = zis.getNextEntry();
		
		//获得实体名称
		System.out.println(entry.getName());
//		System.out.println(entry1.getName());
//		System.out.println(entry2.getName());
		
		zis.close();
		
	}

}

从上面的代码中发现,通过ZiphiputStream类中的getNextEntry()方法可以依次取得每一个 Z i p E n t r y , 那 么 将 此 类 与 Z i p F i l e 结 合 就 可 以 对 压 缩 的 文 件 夹 进 行 解 压 缩 的 操 作 。 但 是 需 要 注 意 的 是 , 在 m l d n d i r. z i p 文 件 中 本 身 是 包 含 压 缩 的 文 件 夹 的 , 所 以 在 进 行 解压缩之前,应该先根据 Z I P 文 件 中 的 文 件 夹 名 称 在 硬 盘 上 创 建 好 一 个 对 应 的 文 件 夹 , 然 后 才 能 把 文 件 解 压 缩 进 去 而 且在操作时对于每一个解压缩的文件都必须先创建(File类的createNewFile()方法可以创建新文件) 后再将内容输出。

【例12.66】解压缩mldndir.zip文件

package jiaqi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;


public class demo434_1 {

	public static void main(String[] args) throws Exception
	{
		//找到压缩文件
		File file = new File("d:"+File.separator+"mldndir.zip");
		//定义输出文件对象
		File outfile = null;
		//压缩包
		ZipFile zipfile = new ZipFile(file);
		//压缩包输入流
		ZipInputStream zipinput = new ZipInputStream(new FileInputStream(file));
		//实体
		ZipEntry entry = null;
		
		//输入实体
		InputStream input = null;
		//输出实体
		OutputStream out = null;
		
		while ((entry = zipinput.getNextEntry()) != null)
		{
//			System.out.println(file.getName());
//			System.out.println("d:" + File.separator + entry.getName());
			
			//实体的输入流
			input = zipfile.getInputStream(entry);
			//输出文件的对象
			outfile = new File("d:" + File.separator + entry.getName());
			
			//***.txt的祖宗级不存在,创建
			if(!outfile.getParentFile().exists())
			{
				outfile.getParentFile().mkdirs();//推荐
			}
			//***.txt不存在,创建
			if(!outfile.exists())
			{
				outfile.createNewFile();
			}
			
			
			//输出流
			out = new FileOutputStream(outfile);
			
			int temp = 0;
			while((temp = input.read())!=-1)
			{
				out.write(temp);
			}
			
			input.close();
			out.close();
		}
		
	}
}