Java培训笔记二十一()

特殊流类型:
1,RandomAccessFile
2,压缩与解压:zip/rar,jar,Gzip
 (1)zip:<1>zipOutputStream
        <2>DataOutputStream
        <3>zipEntry
 (2)GZip:GZipOutputStream
 (3)jar:<1>JarOutputStream
        <2>JarEntry
        <3>Attribute
3,管道流:PipedInputstream
          PipedOutputstream

 

 

import java.io.*;

import java.util.zip.*;

/** *//**

*功能:zip压缩、解压

*说明:本程序通过ZipOutputStream和ZipInputStream实现了zip压缩和解压功能.

*问题:由于java.util.zip包并不支持汉字,当zip文件中有名字为中文的文件时

, author by http://www.bt285.cn http://www.5a520.cn

* 就会出现异常:"Exception in thread "main " java.lang.IllegalArgumentException

* at java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:285)

*解决:

*  方法1、修改import java.util.zip.ZipInputStream和ZipOutputStream.

* java.util.zip只支持UTF-8,Ant里面可以指定编码.

*  方法2、使用Apache Ant里提供的zip工具。

* 不使用java.util.zip的包,把ant.jar放到classpath中.

* 程序中使用import org.apache.tools.zip.*;

*

*仅供编程学习参考.

*

*@author Winty

*@date 2008-8-3

*@Usage:

* 压缩:java Zip -zip "directoryName"

* 解压:java Zip -unzip "fileName.zip"

*/

 

public class Zip{

private ZipInputStream zipIn; //解压Zip

private ZipOutputStream zipOut; //压缩Zip

private ZipEntry zipEntry;

private static int bufSize; //size of bytes

private byte[] buf;

private int readedBytes;

 

public Zip(){

this(512);

}

 

public Zip(int bufSize){

this.bufSize = bufSize;

this.buf = new byte[this.bufSize];

}

 

//压缩文件夹内的文件

public void doZip(String zipDirectory){//zipDirectoryPath:需要压缩的文件夹名

File file;

File zipDir;

 

zipDir = new File(zipDirectory);

String zipFileName = zipDir.getName() + ".zip";//压缩后生成的zip文件名

 

try{

this.zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFileName)));

handleDir(zipDir , this.zipOut);

this.zipOut.close();

}catch(IOException ioe){

ioe.printStackTrace();

}

}

 

//由doZip调用,递归完成目录文件读取

private void handleDir(File dir , ZipOutputStream zipOut)throws IOException{

FileInputStream fileIn;

File[] files;

 

files = dir.listFiles();

 

if(files.length == 0){//如果目录为空,则单独创建之.

//ZipEntry的isDirectory()方法中,目录以"/"结尾.

this.zipOut.putNextEntry(new ZipEntry(dir.toString() + "/"));

this.zipOut.closeEntry();

}

else{//如果目录不为空,则分别处理目录和文件.

for(File fileName : files){

//System.out.println(fileName);

 

if(fileName.isDirectory()){

handleDir(fileName , this.zipOut);

}

else{

fileIn = new FileInputStream(fileName);

this.zipOut.putNextEntry(new ZipEntry(fileName.toString()));

 

while((this.readedBytes = fileIn.read(this.buf))>0){

this.zipOut.write(this.buf , 0 , this.readedBytes);

}

 

this.zipOut.closeEntry();

}

}

}

}

 

//解压指定zip文件

public void unZip(String unZipfileName){//unZipfileName需要解压的zip文件名

FileOutputStream fileOut;

File file;

 

try{

this.zipIn = new ZipInputStream (new BufferedInputStream(new FileInputStream(unZipfileName)));

 

while((this.zipEntry = this.zipIn.getNextEntry()) != null){

file = new File(this.zipEntry.getName());

//System.out.println(file);///

 

if(this.zipEntry.isDirectory()){

file.mkdirs();

}

else{

//如果指定文件的目录不存在,则创建之.

File parent = file.getParentFile();

if(!parent.exists()){

parent.mkdirs();

}

 

fileOut = new FileOutputStream(file);

while(( this.readedBytes = this.zipIn.read(this.buf) ) > 0){

fileOut.write(this.buf , 0 , this.readedBytes );

}

fileOut.close();

}

this.zipIn.closeEntry();

}

}catch(IOException ioe){

ioe.printStackTrace();

}

}

 

//设置缓冲区大小

public void setBufSize(int bufSize){

this.bufSize = bufSize;

}

 

//测试Zip类

public static void main(String[] args)throws Exception{

if(args.length==2){

String name = args[1];

Zip zip = new Zip();

 

if(args[0].equals("-zip"))

zip.doZip(name);

else if(args[0].equals("-unzip"))

zip.unZip(name);

}

else{

System.out.println("Usage:");

System.out.println("压缩:java Zip -zip http://www.bt285.cn /directoryName");

System.out.println("解压:java Zip -unzip http://www.feng123.com /fileName.zip");

throw new Exception("Arguments error!");

}

}

}

 

 

读书笔记: Java 压缩数据流

Zip和GZIP是最常用的压缩格式,能被多种工具来读写.


压缩类 功能

CheckedInputStream GetCheckSum()为任何InputStream产生校验和(不仅是解压)
CheckedOutputStream GetCheckSum()为任何OutputStream产生校验和(不仅是解压)
DeflaterOutputStream 用于压缩类的基础类
ZipOutputStream 一个DeflaterOutputStream,将数据压缩成Zip文件格式
GZIPOutputStream 一个DeflaterOutputStream,将数据压缩成GZIP文件格式
InflaterInputStream 用于解压类的基础类
ZipInputStream 一个DeflaterInputStream,解压用Zip文件格式保存的数据
GZIPInputStream 一个DeflaterInputStream,解压用GZIP文件格式保存的数据


用GZIP进行简单压缩
GZIP接口非常简单,所以如果只有单个数据流需要压缩(而不是一系列不同的数据),那么它就可能是最适当选择。下面是对单个文件进行压缩的例子:

//: GZIPcompress.java
// Uses Java 1.1 GZIP compression to compress
// a file whose name is passed on the command
// line.
import java.io.*;
import java.util.zip.*;

public class GZIPcompress {
  public static void main(String[] args) {
    try {
      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 =e="COLOR: #000000"> in2.readLine()) != null)
  System.out.println(s);
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
} ///:~

压缩类的用法非常直观——只需将输出流封装到一个GZIPOutputStream或者ZipOutputStream内,并将输入流封装到GZIPInputStream或者ZipInputStream内即可。剩余的全部操作就是标准的IO读写。然而,这是一个很典型的例子,我们不得不混合使用新旧IO流:数据的输入使用Reader类,而GZIPOutputStream的构建器只能接收一个OutputStream对象,不能接收Writer对象。

用Zip进行多文件保存
提供了Zip支持的Java库显得更加全面。利用它可以方便地保存多个文件。甚至有一个独立的类来简化对Zip文件的读操作。这个库采采用的是标准Zip格式,所以能与当前因特网上使用的大量压缩、解压工具很好地协作。下面这个例子采取了与前例相同的形式,但能根据我们需要控制任意数量的命令行参数。除此之外,它展示了如何用Checksum类来计算和校验文件的“校验和”(Checksum)。可选用两种类型的Checksum:Adler32(速度要快一些)和CRC32(慢一些,但更准确)。

//: ZipCompress.java
// Uses Java 1.1 Zip compression to compress
// any number of files whose names are passed
// on the command line.
import java.io.*;
import java.util.*;
import java.util.zip.*;

public class ZipCompress {
  public static void main(String[] args) {
    try {
      FileOutputStream f =
        new FileOutputStream("test.zip");
      CheckedOutputStream csum =
        new CheckedOutputStream(
          f, new Adler32());
      ZipOutputStream out =
        new ZipOutputStream(
          new BufferedOutputStream(csum));
      out.setComment("A test of Java Zipping");
      // Can''t read the above comment, though
      for(int i = 0; i < args.length; i++) {
        System.out.println(
          "Writing file " + args[i]);
        BufferedReader in =
    &n
new FileReader(args[i]));
        out.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(
          new BufferedInputStream(csumi));
      ZipEntry ze;
      System.out.println("Checksum: " +
        csumi.getChecksum().getValue());
      while((ze = in2.getNextEntry()) != null) {
        System.out.println("Reading file " + ze);
        int x;
        while((x = in2.read()) != -1)
          System.out.write(x);
      }
      in2.close();
      //

 // 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
      }
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
} ///:~

对于要加入压缩档的每一个文件,都必须调用putNextEntry(),并将其传递给一个ZipEntry对象。ZipEntry对象包含了一个功能全面的接口,利用它可以获取和设置Zip文件内那个特定的Entry(入口)上能够接受的所有数据:名字、压缩后和压缩前的长度、日期、CRC校验和、额外字段的数据、注释、压缩方法以及它是否一个目录入口等等。然而,虽然Zip格式提供了设置密码的方法,但Java的Zip库没有提供这方面的支持。而且尽管CheckedInputStream和CheckedOutputStream同时提供了对Adler32和CRC32校验和的支持,但是ZipEntry只支持CRC的接口。这虽然属于基层Zip格式的限制,但却限制了我们使用速度更快的Adler32。
为解压文件,ZipInputStream提供了一个getNextEntry()方法,能在有的前提下返回下一个ZipEntry。作为一个更简洁的方法,可以用ZipFile对象读取文件。该对象有一个entries()方法,可以为ZipEntry返回一个Enumeration(枚举)。
为读取校验和,必须多少拥有对关联的Checksum对象的访问权限。在这里保留了指向CheckedOutputStream和CheckedInputStream对象的一个句柄。但是,也可以只占有指向Checksum对象的一个句柄。
Zip流中一个令人困惑的方法是setComment()。正如前面展示的那样,我们可在写一个文件时设置注释内容,但却没有办法取出ZipInputStream内的注释。看起来,似乎只能通过ZipEntry逐个入口地提供对注释的完全支持。
当然,使用GZIP或Zip库时并不仅仅限于文件——可以压缩任何东西,包括要通过网络连接发送的数据。

 

 

 

ZIP压缩类
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipCompress ...{

    /** *//**
     * @param args
     */
    public static void main(String[] args) throws IOException ...{
        compress("D:/tomcat-5.5.20","d:/test/testZip.zip");
    }
    /** *//**
     * 递归压缩文件
     * @param source 源路径,可以是文件,也可以目录
     * @param destinct  目标路径,压缩文件名
     * @throws IOException
     */
    private static void compress(String source,String destinct) throws IOException ...{
        List fileList=loadFilename(new File(source));
        ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(new File(destinct)));
       
        byte[] buffere=new byte[8192];
        int length;
        BufferedInputStream bis;
       
        for(int i=0;i<fileList.size();i++) ...{
            File file=(File) fileList.get(i);
            zos.putNextEntry(new ZipEntry(getEntryName(source,file)));
            bis=new BufferedInputStream(new FileInputStream(file));
           
            while(true) ...{
                length=bis.read(buffere);
                if(length==-1) break;
                zos.write(buffere,0,length);
            }
            bis.close();
            zos.closeEntry();
        }
        zos.close();
    }
    /** *//**
     * 递归获得该文件下所有文件名(不包括目录名)
     * @param file
     * @return
     */
    private static List loadFilename(File file) ...{
        List filenameList=new ArrayList();
        if(file.isFile()) ...{
            filenameList.add(file);
        }
        if(file.isDirectory()) ...{
            for(File f:file.listFiles()) ...{
                filenameList.addAll(loadFilename(f));
            }
        }
        return filenameList;
    }
    /** *//**
     * 获得zip entry 字符串
     * @param base
     * @param file
     * @return
     */
    private static String getEntryName(String base,File file) ...{
        File baseFile=new File(base);
        String filename=file.getPath();
        //int index=filename.lastIndexOf(baseFile.getName());
        if(baseFile.getParentFile().getParentFile()==null)
            return filename.substring(baseFile.getParent().length());
        return filename.substring(baseFile.getParent().length()+1);
    }
}

ZIP解压类

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class ZipDecompression ...{

    /** *//**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException ...{
        decompression("d:/test/testZip.zip","d:/test/un");
    }
    /** *//**
     * 解压ZIP文件
     * @param zipFile  要解压的ZIP文件路径
     * @param destination  解压到哪里
     * @throws IOException
     */
    public static void decompression(String zipFile,String destination) throws IOException ...{
        ZipFile zip=new ZipFile(zipFile);
        Enumeration en=zip.entries();
        ZipEntry entry=null;
        byte[] buffer=new byte[8192];
        int length=-1;
        InputStream input=null;
        BufferedOutputStream bos=null;
        File file=null;
       
        while(en.hasMoreElements()) ...{
            entry=(ZipEntry)en.nextElement();
            if(entry.isDirectory()) ...{
                System.out.println("directory");
                continue;
            }
           
            input=zip.getInputStream(entry);
            file=new File(destination,entry.getName());
            if(!file.getParentFile().exists()) ...{
                file.getParentFile().mkdirs();
            }
            bos=new BufferedOutputStream(new FileOutputStream(file));
           
            while(true) ...{
                length=input.read(buffer);
                if(length==-1) break;
                bos.write(buffer,0,length);
            }
            bos.close();
            input.close();
        }
        zip.close();
    }
}

 

 

package com.tw.file.util;  
 
import java.io.BufferedInputStream;  
import java.io.BufferedOutputStream;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.util.ArrayList;  
import java.util.Collection;  
import java.util.Enumeration;  
import java.util.zip.ZipEntry;  
import java.util.zip.ZipFile;  
import java.util.zip.ZipOutputStream;  
 
public class Zip2Utils {  
 
    /** 
     * @param args 
     */ 
    public static void main(String[] args) {  
      
        Collection<File> resFileList = new ArrayList<File>();   
        resFileList.add(new File("E://1.txt"));   
        resFileList.add(new File("E://2.txt"));   
        File zipFile = new File("e://txxxt.zip");   
 
        try {  
            Zip2Utils.zipFiles(resFileList, zipFile);   //测试OK  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }   
 
    }  
      
     private static final int BUFF_SIZE = 1024 * 1024;     //1M Byte   
 
     /**  
      * 批量压缩文件(夹)  
      *  
      * @param resFileList 要压缩的文件(夹)列表  
      * @param zipFile         生成的压缩文件  
      * @throws IOException 当压缩过程出错时抛出  
      */   
     public static void zipFiles(Collection<File> resFileList, File zipFile) throws IOException {   
             ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));   
             for (File resFile : resFileList) {   
                     zipFile(resFile, zipout, "");   
             }   
             zipout.close();   
     }   
 
     /**  
      * 批量压缩文件(夹)  
      *  
      * @param resFileList 要压缩的文件(夹)列表  
      * @param zipFile         生成的压缩文件  
      * @param comment         压缩文件的注释  
      * @throws IOException 当压缩过程出错时抛出  
      */   
     public static void zipFiles(Collection<File> resFileList, File zipFile, String comment) throws IOException {   
             ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));   
             for (File resFile : resFileList) {   
                     zipFile(resFile, zipout, "");   
             }   
             zipout.setComment(comment);   
             zipout.close();   
     }   
 
     /**  
      * 解压缩一个文件  
      *  
      * @param zipFile        压缩文件  
      * @param folderPath 解压缩的目标目录  
      * @throws IOException 当压缩过程出错时抛出  
      */   
     public static void upZipFile(File zipFile, String folderPath) throws IOException {   
             ZipFile zf = new ZipFile(zipFile);   
             for (Enumeration entries = zf.entries(); entries.hasMoreElements();) {   
                     ZipEntry entry = ((ZipEntry) entries.nextElement());   
                     InputStream in = zf.getInputStream(entry);   
                     OutputStream out = new FileOutputStream(folderPath + File.separator + entry.getName());   
                     byte buffer[] = new byte[BUFF_SIZE];   
                     int realLength;   
                     while ((realLength = in.read(buffer)) > 0) {   
                             out.write(buffer, 0, realLength);   
                     }   
                     in.close();   
                     out.close();   
             }   
     }   
 
     private static void zipFile(File resFile, ZipOutputStream zipout, String rootpath) throws IOException {   
             rootpath = rootpath + (rootpath.trim().length() == 0 ? "" : File.separator) + resFile.getName();   
             if (resFile.isDirectory()) {   
                     File[] fileList = resFile.listFiles();   
                     for (File file : fileList) {   
                             zipFile(file, zipout, rootpath);   
                     }   
             } else {   
                     byte buffer[] = new byte[BUFF_SIZE];   
                     BufferedInputStream in = new BufferedInputStream(new FileInputStream(resFile), BUFF_SIZE);   
                     zipout.putNextEntry(new ZipEntry(rootpath));   
                     int realLength;   
                     while ((realLength = in.read(buffer)) != -1) {   
                             zipout.write(buffer, 0, realLength);   
                     }   
                     in.close();   
                     zipout.flush();   
                     zipout.closeEntry();   
             }   
     }   
 
      

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值