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 R
或 W 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
几个类完成操作.
表12-19 ZipEntry类的常用方法
序 号 方 法 类 型 描 述
1 public ZipEntry(String name) 构造 创建对象并指定要创建的ZipEntry名称
2 public boolean isDirectory() 普通 判断此ZipEntry是否是目录
压缩的输入/输出类是定义在java.utii.zip
包中。压缩的输入/输出流也属于InputStream
或OutputStream
的子类,但是却没有定义在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();
}
}
结果:
【例12.62】压缩一个文件夹
针对的是:文件加下全部是具体文件。没有嵌套的文件加
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 类
ZiplnputStream
是InputStream
的子类,通过此类,可以方便地读取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();
}
}
}