Java 实现文件压缩与解压的示例 [zip 格式, gzip 格式]
这里有新鲜出炉的 Java 设计模式, 程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言, 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台 (即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se)) 的总称
本篇文章主要介绍了 Java 实现文件压缩与解压的示例[zip 格式, gzip 格式], 具有一定的参考价值, 感兴趣的小伙伴们可以参考一下
Java 实现 ZIP 的解压与压缩功能基本都是使用了 Java 的多肽和递归技术, 可以对单个文件和任意级联文件夹进行压缩和解压, 对于一些初学者来说是个很不错的实例
zip 扮演着归档和压缩两个角色; gzip 并不将文件归档, 仅只是对单个文件进行压缩, 所以, 在 UNIX 平台上, 命令 tar 通常用来创建一个档案文件, 然后命令 gzip 来将档案文件压缩
Java I/O 类库还收录了一些能读写压缩格式流的类要想提供压缩功能, 只要把它们包在已有的 I/O 类的外面就行了这些类不是 Reader 和 Writer, 而是 InputStream 和 OutStreamput 的子类这是因为压缩算法是针对 byte 而不是字符的
相关类与接口:
Checksum 接口: 被类 Adler32 和 CRC32 实现的接口
Adler32 : 使用 Alder32 算法来计算 Checksum 数目
CRC32 : 使用 CRC32 算法来计算 Checksum 数目
CheckedInputStream :InputStream 派生类, 可得到输入流的校验和 Checksum, 用于校验数据的完整性
CheckedOutputStream :OutputStream 派生类, 可得到输出流的校验和 Checksum, 用于校验数据的完整性
DeflaterOutputStream : 压缩类的基类
ZipOutputStream :DeflaterOutputStream 的一个子类, 把数据压缩成 Zip 文件格式
GZIPOutputStream :DeflaterOutputStream 的一个子类, 把数据压缩成 GZip 文件格式
InflaterInputStream : 解压缩类的基类
ZipInputStream :InflaterInputStream 的一个子类, 能解压缩 Zip 格式的数据
GZIPInputStream :InflaterInputStream 的一个子类, 能解压缩 Zip 格式的数据
ZipEntry 类: 表示 ZIP 文件条目
ZipFile 类: 此类用于从 ZIP 文件读取条目
使用 ZIP 对多个文件进行压缩与解压
Java 对 Zip 格式类库支持得比较全面, 得用它可以把多个文件压缩成一个压缩包这个类库使用的是标准 Zip 格式, 所以能与很多的压缩工具兼容
ZipOutputStream 类有设置压缩方法以及在压缩方式下使用的压缩级别, zipOutputStream.setMethod(int method)设置用于条目的默认压缩方法只要没有为单个 ZIP 文件条目指定压缩方法, 就使用 ZipOutputStream 所设置的压缩方法来存储, 默认值为 ZipOutputStream.DEFLATED(表示进行压缩存储), 还可以设置成 STORED(表示仅打包归档存储)ZipOutputStream 在设置了压缩方法为 DEFLATED 后, 我们还可以进一步使用 setLevel(int level)方法来设置压缩级别, 压缩级别值为 0-9 共 10 个级别(值越大, 表示压缩越利害), 默认为 Deflater.DEFAULT_COMPRESSION=-1 当然我们也可以通过条目 ZipEntry 的 setMethod 方法为单个条件设置压缩方法
类 ZipEntry 描述了存储在 ZIP 文件中的压缩文件类中包含有多种方法可以用来设置和获得 ZIP 条目的信息类 ZipEntry 是被 ZipFile[zipFile.getInputStream(ZipEntry entry)]和 ZipInputStream 使用来读取 ZIP 文件, ZipOutputStream 来写入 ZIP 文件的有以下这些有用的方法: getName()返回条目名称 isDirectory()如果为目录条目, 则返回 true(目录条目定义为其名称以 /' 结尾的条目)setMethod(int method) 设置条目的压缩方法, 可以为 ZipOutputStream.STORED 或 ZipOutputStream .DEFLATED
下面实例我们使用了 apache 的 zip 工具包(所在包为 ant.jar ), 因为 java 类型自带的不支持中文路径, 不过两者使用的方式是一样的, 只是 apache 压缩工具多了设置编码方式的接口, 其他基本上是一样的另外, 如果使用 org.apache.tools.zip.ZipOutputStream 来压缩的话, 我们只能使用 org.apache.tools.zip.ZipEntry 来解压, 而不能使用 java.util.zip.ZipInputStream 来解压读取了, 当然 apache 并未提供 ZipInputStream 类
文件压缩:
- package gizAction;
- import java.io. * ;
- import java.util.zip. * ;
- /**
- * @author Dana.Li
- * <p>
- * 程序实现了 ZIP 压缩[compression]
- * <p>
- * 大致功能包括用了多态, 递归等 JAVA 核心技术, 可以对单个文件和任意级联文件夹进行压缩和解压 需在代码中自定义源输入路径和目标输出路径
- * <p>
- * 在本段代码中, 实现的是压缩部分
- */
- public class ZipCompressing {
- private int k = 1; // 定义递归次数变量
- private void zip(String zipFileName, File inputFile) throws Exception {
- System.out.println("压缩中...");
- ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
- BufferedOutputStream bo = new BufferedOutputStream(out);
- zip(out, inputFile, inputFile.getName(), bo);
- bo.close();
- out.close(); // 输出流关闭
- System.out.println("压缩完成");
- }
- private void zip(ZipOutputStream out, File f, String base, BufferedOutputStream bo) throws Exception { // 方法重载
- if (f.isDirectory()) {
- File[] fl = f.listFiles();
- if (fl.length == 0) {
- out.putNextEntry(new ZipEntry(base + "/")); // 创建 zip 压缩进入点 base
- System.out.println(base + "/");
- }
- for (int i = 0; i < fl.length; i++) {
- zip(out, fl[i], base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
- }
- System.out.println("第" + k + "次递归");
- k++;
- } else {
- out.putNextEntry(new ZipEntry(base)); // 创建 zip 压缩进入点 base
- System.out.println(base);
- FileInputStream in =new FileInputStream(f);
- BufferedInputStream bi = new BufferedInputStream( in );
- int b;
- while ((b = bi.read()) != -1) {
- bo.write(b); // 将字节流写入当前 zip 目录
- }
- bi.close(); in .close(); // 输入流关闭
- }
- }
- /**
- * 测试
- * @param args
- */
- public static void main(String[] args) {
- ZipCompressing book = new ZipCompressing();
- try {
- book.zip("F:\\ziptest.zip", new File("F:\\ziptest"));
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
- }
文件解压:
- package gizAction;
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipInputStream;
- /**
- * @author Dana.Li
- * <p>
- * 程序实现了 ZIP 解压[decompression]
- * <p>
- * 大致功能包括用了多态, 递归等 JAVA 核心技术, 可以对单个文件和任意级联文件夹进行压缩和解压 需在代码中自定义源输入路径和目标输出路径
- * <p>
- * 在本段代码中, 实现的是解压部分;
- */
- public class zipDecompressing {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- long startTime = System.currentTimeMillis();
- try {
- ZipInputStream Zin = new ZipInputStream(new FileInputStream("F:\\ziptest.zip")); // 输入源 zip 路径
- BufferedInputStream Bin = new BufferedInputStream(Zin);
- String Parent = "F:\\ziptest\\"; // 输出路径(文件夹目录)
- File Fout = null;
- ZipEntry entry;
- try {
- while ((entry = Zin.getNextEntry()) != null && !entry.isDirectory()) {
- Fout = new File(Parent, entry.getName());
- if (!Fout.exists()) { (new File(Fout.getParent())).mkdirs();
- }
- FileOutputStream out = new FileOutputStream(Fout);
- BufferedOutputStream Bout = new BufferedOutputStream(out);
- int b;
- while ((b = Bin.read()) != -1) {
- Bout.write(b);
- }
- Bout.close();
- out.close();
- System.out.println(Fout + "解压成功");
- }
- Bin.close();
- Zin.close();
- } catch(IOException e) {
- e.printStackTrace();
- }
- } catch(FileNotFoundException e) {
- e.printStackTrace();
- }
- long endTime = System.currentTimeMillis();
- System.out.println("耗费时间:" + (endTime - startTime) + "ms");
- }
- }
用 GZIP 进行对单个文件压缩
GZIP 的接口比较简单, 因此如果你只需对一个流进行压缩的话, 可以使用它当然它可以压缩字符流, 与可以压缩字节流, 下面是一个对 GBK 编码格式的文本文件进行压缩的
压缩类的用法非常简单; 只要用 GZIPOutputStream 或 ZipOutputStream 把输出流包起来, 再用 GZIPInputStream 或 ZipInputStream 把输入流包起来就行了剩下的都是些普通的 I/O 操作
- import java.io.BufferedOutputStream;
- import java.io.BufferedReader;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.util.zip.GZIPInputStream;
- import java.util.zip.GZIPOutputStream;
- public class GZIPcompress {
- public static void main(String[] args) throws IOException {
- // 做准备压缩一个字符文件, 注, 这里的字符文件要是 GBK 编码方式的
- BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(
- "e:/tmp/source.txt"), "GBK"));
- // 使用 GZIPOutputStream 包装 OutputStream 流, 使其具体压缩特性, 最后会生成 test.txt.gz 压缩包
- // 并且里面有一个名为 test.txt 的文件
- BufferedOutputStream out = new BufferedOutputStream(new GZIPOutputStream(
- new FileOutputStream("test.txt.gz")));
- System.out.println("开始写压缩文件...");
- int c;
- while ((c = in.read()) != -1) {
- /*
- * 注, 这里是压缩一个字符文件, 前面是以字符流来读的, 不能直接存入 c, 因为 c 已是 Unicode
- * 码, 这样会丢掉信息的(当然本身编码格式就不对), 所以这里要以 GBK 来解后再存入
- */
- out.write(String.valueOf((char) c).getBytes("GBK"));
- }
- in.close();
- out.close();
- System.out.println("开始读压缩文件...");
- // 使用 GZIPInputStream 包装 InputStream 流, 使其具有解压特性
- BufferedReader in2 = new BufferedReader(new InputStreamReader(
- new GZIPInputStream(new FileInputStream("test.txt.gz")), "GBK"));
- String s;
- // 读取压缩文件里的内容
- while ((s = in2.readLine()) != null) {
- System.out.println(s);
- }
- in2.close();
- }
- }
来源: http://www.phperz.com/article/18/0211/358940.html