您的位置:首页 > 其它

用 Zip 进行多文件保存

2013-08-26 11:48 369 查看
支持 Zip 格式的 Java 库更加全面。利用它可以方便地保存多个文件,甚至有一个独立的

类使得读取 Zip 文件更加方便。这个类库使用的是标准 Zip 格式,所以能与当前那些可通

过因特网下载到的压缩工具很好地协作。下面这个例子具有与前例相同的形式,但它能根据

需要来处理任意多个命令行参数。另外,它示例了用 Checksum 类来计算和校验文件的“校

验和”(Checksum)的方法。一共有两种 Checksum 类型:Adler32(速度要快一些)

和 CRC32(慢一些,但更准确)。

//: c12:ZipCompress.java

// Uses Zip compression to compress any

// number of files given on the command line.

// {Args: ZipCompress.java}

// {Clean: test.zip}

import com.bruceeckel.simpletest.*;

import java.io.*;

import java.util.*;

import java.util.zip.*; 

public class ZipCompress {

    private static Test monitor = new Test();

    // Throw exceptions to console:

    public static void main(String[] args)

  throws IOException {

    FileOutputStream f = new FileOutputStream("test.zip");

    CheckedOutputStream csum =

      new CheckedOutputStream(f, new Adler32());

          ZipOutputStream zos = new ZipOutputStream(csum);

     BufferedOutputStream out = 

      new BufferedOutputStream(zos);

        zos.setComment("A test of Java Zipping");

        // No corresponding getComment(), though.

        for(int i = 0; i < args.length; i++) {

      System.out.println("Writing file " + args[i]);

            BufferedReader in = 

                new BufferedReader(new FileReader(args[i]));

      zos.putNextEntry(new ZipEntry(args[i]));

            int c; 

      while((c = in.read()) != -1) 

                out.write(c); 

            in.close(); 

        } 

        out.close(); 

        // Checksum valid only after the file has been closed!

    System.out.println("Checksum: " +

      csum.getChecksum().getValue());

    // Now extract the files:

    System.out.println("Reading file");

    FileInputStream fi = new FileInputStream("test.zip");

    CheckedInputStream csumi =

      new CheckedInputStream(fi, new Adler32());

    ZipInputStream in2 = new ZipInputStream(csumi);

        BufferedInputStream bis = new BufferedInputStream(in2);

        ZipEntry ze; 

        while((ze = in2.getNextEntry()) != null) {

      System.out.println("Reading file " + ze);

            int x; 

      while((x = bis.read()) != -1)

                System.out.write(x); 

        } 

    if(args.length == 1)

      monitor.expect(new String[] {

                "Writing file " + args[0], 

                "%% Checksum: \\d+", 

                "Reading file", 

        "Reading file " + args[0]}, args[0]); 

    System.out.println("Checksum: " +

      csumi.getChecksum().getValue());

    bis.close();

        // Alternative way to open and read zip files:

    ZipFile zf = new ZipFile("test.zip");

    Enumeration e = zf.entries();

    while(e.hasMoreElements()) {

      ZipEntry ze2 = (ZipEntry)e.nextElement();

      System.out.println("File: " + ze2);

            // ... and extract the data as before

        } 

    if(args.length == 1)

      monitor.expect(new String[] {

                "%% Checksum: \\d+", 

                "File: " + args[0] 

            }); 

    } 

} ///:~

对于每一个要加入压缩文档的文件,都必须调用 putNextEntry(),并将其传递给一个

ZipEntry 对象。ZipEntry 对象包含了一个功能广泛的接口,允许你获取和设置 Zip 文件

内该特定项上所有可利用的数据:名字、压缩的和未压缩的文件大小、日期、CRC 校验和、

额外域的数据、注释、压缩方法以及它是否是一个目录入口等等。然而,即使 Zip 格式提

供了设置密码的方法,但 Java 的 Zip 类库并不提供这方面的支持。虽然

CheckedInputStream 和 CheckedOutputStream 同时支持 Adler32 和 CRC32 两种类

型的校验和,但是 ZipEntry 类只有一个支持 CRC 的接口。虽然这是一个底层 Zip 格式的

限制,但却限制了你不能使用速度更快的 Adler32。

为了能够解压缩文件,ZipInputStream 提供了一个 getNextEntry()方法返回下一个

ZipEntry,如果该 ZipEdtry 存在的话。有一个更简便的方法来解压缩文件——利用 ZipFile

对象读取文件。该对象有一个 entries()方法用来向 ZipEntry 返回一个 Enumeration(枚

举)。

如果要读取校验和,必须拥有对与之相关联的 Checksum 对象的访问权限。在这里保留了

指向 CheckedOutputStream 和 CheckedInputStream 对象的一个引用。但是,也可以

只保留一个指向 Checksum 对象的引用。

Zip 流中有一个令人困惑的方法 setComment()。正如在前面 ZipCompress.java 中所示,

我们可以在写一个文件时写注释,但却没有任何方法恢复 ZipInputStream 内的注释。似

乎只能通过 ZipEntry,注释才能完全在逐条获取的基础上被支持。

当然,GZIP 或 Zip 库的使用并不仅仅局限于文件——它可以压缩任何东西,包括需要通过
网络发送的数据。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: