表格中CheckedInputStream 和 CheckedOutputStream 一般会和Zip压缩解压过程配合使用,主要是为了保证我们压缩和解压过程数据包的正确性,得到的是中间没有被篡改过的数据。
我们以CheckedInputStream 为例,它的构造器需要传入一个Checksum类型:
1 public CheckedInputStream(InputStream in, Checksum cksum) {2 super(in);
3 this.cksum = cksum;
4 }
而Checksum 是一个接口,可以看到这里又用到了策略模式,具体的校验算法是可以选择的。Java类库给我提供了两种校验和算法:Adler32 和 CRC32,性能方面可能Adler32 会更好一些,不过CRC32可能更准确。各有优劣吧。
好了,接下来看下压缩/解压缩流的具体使用。
将多个文件压缩成zip包
1public class ZipFileUtils {2 public static void compressFiles(File[] files, String zipPath) throws IOException {
3
4 // 定义文件输出流,表明是要压缩成zip文件的
5 FileOutputStream f = new FileOutputStream(zipPath);
6
7 // 给输出流增加校验功能
8 CheckedOutputStream checkedOs = new CheckedOutputStream(f,new Adler32());
9
10 // 定义zip格式的输出流,这里要明白一直在使用装饰器模式在给流添加功能
11 // ZipOutputStream 也是从FilterOutputStream 继承下来的
12 ZipOutputStream zipOut = new ZipOutputStream(checkedOs);
13
14 // 增加缓冲功能,提高性能
15 BufferedOutputStream buffOut = new BufferedOutputStream(zipOut);
16
17 //对于压缩输出流我们可以设置个注释
18 zipOut.setComment("zip test");
19
20 // 下面就是从Files[] 数组中读入一批文件,然后写入zip包的过程
21 for (File file : files){
22
23 // 建立读取文件的缓冲流,同样是装饰器模式使用BufferedReader
24 // 包装了FileReader
25 BufferedReader bfReadr = new BufferedReader(new FileReader(file));
26
27 // 一个文件对象在zip流中用一个ZipEntry表示,使用putNextEntry添加到zip流中
28 zipOut.putNextEntry(new ZipEntry(file.getName()));
29
30 int c;
31 while ((c = bfReadr.read()) != -1){
32 buffOut.write(c);
33 }
34
35 // 注意这里要关闭
36 bfReadr.close();
37 buffOut.flush();
38 }
39 buffOut.close();
40 }
41
42 public static void main(String[] args) throws IOException {
43 String dir = "d:";
44 String zipPath = "d:/test.zip";
45 File[] files = Directory.getLocalFiles(dir,".*\\.txt");
46 ZipFileUtils.compressFiles(files, zipPath);
47 }
48}
在main函数中我们使用了本文中 File其实是个工具类 章节里的Directory工具类。