• ThinkJava-压缩


    尽管存在许多种压缩算恙,但是Zip和GZIP可能是最常用的.因此我们可以很容易地使用多
    种可读写这些格式的工具来操纵我们的压缩数据。
     
    1 用GZIP进行简单压缩
    GZIP接口非常简单, 因此如果我们只想对单个数据流(而不是一系列互异数据)进行压缩,
    那么它可能是比较适合的选择。下面是对单个文件进行压缩的例子:
    // {Args: GZIPcompress.java}
    package com.java.io;
    
    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    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 {
            if(args.length == 0) {
              System.out.println(
                "Usage: 
    GZIPcompress file
    " +
                "	Uses GZIP compression to compress " +
                "the file to test.gz");
              System.exit(1);
            }
            BufferedReader in = new BufferedReader(new FileReader(args[0]));
            BufferedOutputStream out = new BufferedOutputStream(
                                              new GZIPOutputStream(
                                                new FileOutputStream("test.gz")));
            System.out.println("Writing file");
            int c;
            while((c = in.read()) != -1){
                out.write(c);
            }
            in.close();
            out.close();
            System.out.println("Reading file");
            BufferedReader in2 = new BufferedReader(
                                      new InputStreamReader(new GZIPInputStream(
                                        new FileInputStream("test.gz"))));
            String s;
            while((s = in2.readLine()) != null){
                System.out.println(s);
            }
            in2.close();
          }
    }
    View Code
    压缩类的使用非常直观一一直接将输出流封装成GZlPOutputStream或ZipOutputStream,并将
    输入流封装成GZIPInputStream或ZipInputStream即可。其他全部操作就是通常的IO读写。这个例
    子把面向字符的流和面向字节的流棍合了起来,输入(in ) 用Reader类,而GZIPOutputStream的
    构造器只能接受OutputStream对象,不能接受Writer对象。在打开文件时, GZIPInputStream就会
    被转换成Reader.
     

    2.用Zip进行多文件保存
    支持Zip格式的Java 库更加全面.利用该库可以方便地保存多个文件,它甚至有一个独立的
    类,使得读取Zip文件更加方便.这个类库使用的是标准Zip格式,所以能与当前那些可通过因
    特网下载的压缩工具很好地协作. 下面这个例子具有与前例相同的形式,但它能根据需要来处
    理任意多个命令行参数。另外,它显示了用Checksum类来计算和校验文件的校验和的方法。
    共有两利Checksum类型: Adler32 (它快一些) 和CRC32 (慢一些, 但更准确)。
    // Uses Zip compression to compress any
    // number of files given on the command line.
    // {Args: ZipCompress.java}
    package com.java.io;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Enumeration;
    import java.util.zip.Adler32;
    import java.util.zip.CheckedInputStream;
    import java.util.zip.CheckedOutputStream;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    import java.util.zip.ZipInputStream;
    import java.util.zip.ZipOutputStream;
    
    import static com.java.util.Print.*;
    
    public class ZipCompress {
        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(String arg : args) {
                print("Writing file " + arg);
                BufferedReader in = new BufferedReader(new FileReader(arg));
                zos.putNextEntry(new ZipEntry(arg));
                int c;
                while((c = in.read()) != -1){
                    out.write(c);
                }
                in.close();
                out.flush();
            }
            out.close();
            
            // Checksum valid only after the file has been closed!
            print("Checksum: " + csum.getChecksum().getValue());
            
            // Now extract the files:
            print("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) {
                print("Reading file " + ze);
                int x;
                while((x = bis.read()) != -1){
                    System.out.write(x);
                }
            }
            if(args.length == 1){
                print("Checksum: " + csumi.getChecksum().getValue());
            }
            bis.close();
            
            // Alternative way to open and read Zip files:
            ZipFile zf = new ZipFile("test.zip");
            Enumeration<? extends ZipEntry> e = zf.entries();
            while(e.hasMoreElements()) {
                ZipEntry ze2 = e.nextElement();
                print("File: " + ze2);
                // ... and extract the data as before
            }
        }
    }
    View Code
      对于每一个要加入压缩档案的文件,都必须调用putNextEntry() ,并将其传递给一个
    ZlpEntry对象。ZipEntry对象包含了一个功能很广泛的接口,允许你获取和设置Zip文件内该特
    定项上所有可利用的数据: 名字、压缩的和未压缩的文件大小、日期、CRC校验和、额外字段数
    据、注释、压缩方法以及它是否是一个目录入口等等.然而,尽管Zip格式提供了设置密码的方
    法.但Jav啪Zip类库并不提供这方面的支持。虽然CheckedlnputStream和CheckedOutputStream
    都支持Adler32和CRC32两种类型的校验和,但是ZjpEntry类只有一个支持CRC的接口.虽然这
    是一个底层Zip格式的限制,但却限制了人们不能使用速度更快的Adler32 .
      为了能够解压缩文件, ZiplnputStream提供了一个getNextEntry()方法返回下一个ZipEntry
    (如果存在的话).。解压缩文件有一个更简便的方法一一利用ZipFile对象读取文件。该对象有一
    个entries()方法用来向ZipEntries返回一个Enumeration (枚举).
      为了读取校验和,必须拥有对与之相关联的Checksum对象的访问权限。在这里保留了指向
    CheckedOutputStream和CheckedlnputStream对象的引用.但是,也可以只保留一个指向Checksum对象的引用。
      Zip流中有一个令人困惑的方法setComment() . 正如前面ZipCompress.java中所示, 我们可
    以在写文件时写注释,但却没有任何方法恢复ZiplnputStreaIn内的注释.似乎只能通过ZipEntry ,
    才能以逐条方式完全支持注释的获取。
      当然, GZIP或Zip库的使用并不仅仅局限于文件一它可以压缩任何东西,包括需要通过网络发送的数据.

     3.

    -----------

  • 相关阅读:
    捡到一本<C++ Reference>
    题目1008:最短路径问题
    题目1014:排名
    题目1080:进制转换
    题目1081:递推数列
    题目1086:最小花费
    题目1076:N的阶乘
    题目1035:找出直系亲属
    在Mac上搭建Jenkins环境
    获取鼠标点击UGUI,先对于特定物体的相对坐标
  • 原文地址:https://www.cnblogs.com/tenWood/p/7475879.html
Copyright © 2020-2023  润新知