装饰器模式实现文件IO流的ZIP压缩解压(二)

      接着上篇文章,上一篇文章讲的是将一个文本文件的数据输出流,转换成ZIP的压缩输出流。

      这篇文章,讲述的是,怎样将上一篇文章中生成的压缩文件,进行解压的。也就是说,读取一个ZIP压缩文件,将里面一个被压缩的文件提取出来。

      其实,根据压缩、解压,输入、输出 我们可以写出四个装饰器类,分别完成IO流的输入输出、压缩解压功能。暂时先写两个,后面两个有时间再补。

package houlei.support.util.zip;

import java.io.IOException;
import java.io.InputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * 将一个ZIP输入流解压为普通的输入流,只解压其中的一个文件。
 */
public class ZipFileDecompressInputStream extends InputStream {

	private ZipInputStream in = null;
	
	/**
	 * 构建对象,完成转化。
	 * @param entryFileName 压缩包中保存文件的文件名
	 * @param inputStream 压缩包文件的输入流
	 */
	public ZipFileDecompressInputStream(String entryFileName, InputStream inputStream) throws IOException {
		super();
		CheckedInputStream cis = new CheckedInputStream(inputStream , new CRC32());  
		in = new ZipInputStream(cis);
		ZipEntry entry = null;
		while ((entry = in.getNextEntry()) != null) {
			String name = entry.getName();
			if(name==null && entryFileName==null){
				break;
			}
			if(entryFileName!=null && entryFileName.equals(name)){
				break;
			}
			in.closeEntry();
		}
		if(entry==null){
			throw new IllegalArgumentException("解压的数据实体对象并不存在,entryFileName="+entryFileName);
		}
	}

	@Override
	public int read() throws IOException {
		return in.read();
	}

	@Override
	public void close() throws IOException {
		try{
			in.closeEntry();
		}finally{
			in.close();
		}
	}

	/**
	 * 测试用例
	 */
	public static void main(String[] args) throws Exception{
		final String file = "d:/tmp/1.zip";//待读取的压缩文件的文件名
		final String entry = "text.txt";//压缩包内,待解压的文件名
		java.io.InputStreamReader reader = null;
		try {
			reader = new java.io.InputStreamReader(new ZipFileDecompressInputStream(entry, new java.io.FileInputStream(file)));
			char[] buff = new char[128];
			int len =0;
			while((len = reader.read(buff))>0){
				System.out.print(String.valueOf(buff, 0, len));//打印文本文件的内容,这语句有编码BUG,只做测试使用。
			}
		} catch (IOException e) {
			throw e;
		} finally {
			if(reader!=null){
				reader.close();
			}
		}
		
	}
	
}

看不懂测试用例的同学,我这里也再解释一下。

测试用例里面读取的是一个压缩文件。我们的程序以前可能是读取文本文件的,但是由于文本文件被ZIP压缩了,我们就得读取ZIP文件了。

如果没有包装输入流的话,我们应该读取没被压缩的文本文件,经过包装以后,我们可以读取压缩的ZIP文件了,

但是,只能读取压缩包中的一个文件内容,该文件的文件名在包装输入流的时候,通过参数传递进去了。

包装过后,我们发现,无论读取的是文本文件,还是ZIP压缩文件,我们对文件数据的处理代码,是不用修改的,

我们修改的只是读取的文件名,以及是否对文件输入流进行包装。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值