Java IO 压缩流(ZipOutputStream/ZipInputStream)

时间:2023-02-09 20:16:24

1、了解压缩流的主要作用

2、了解JAVA IO 支持的三种压缩格式

3、掌握ZipOutputStream、ZipFile、ZipInputStream 三个类的作用

具体内容

经常可以看见各种压缩文件:zip、jar、GZ、

Java IO 压缩流(ZipOutputStream/ZipInputStream)

Java IO 压缩流(ZipOutputStream/ZipInputStream)

正常情况下在IO 操作中,所有的类库都是在 IO 包中。

Java IO 压缩流(ZipOutputStream/ZipInputStream)

在实例化ZipEntry 的时候,要设置名称,此名称实际上就是压缩文件中每一个元素的名称。

1、ZipOutputStream

Java IO 压缩流(ZipOutputStream/ZipInputStream)

此类的功能就是完成ZIP格式输出的。

继承关系:

java.lang.Object
  java.io.OutputStream
      java.io.FilterOutputStream
          java.util.zip.DeflaterOutputStream
              java.util.zip.ZipOutputStream

从定义可以发现,就是一个字节的输出流。

public void putNextEntry(ZipEntry e)
                  throws IOException
在压缩文件中,每一个压缩的内容都可以用一个ZipEntry 表示,所以在进行压缩之前必须通过putNextEntry 设置一个ZipEntry 即可。
  1. import java.io.File ;  
  2. import java.io.FileInputStream ;  
  3. import java.io.InputStream ;  
  4. import java.util.zip.ZipEntry ;  
  5. import java.util.zip.ZipOutputStream ;  
  6. import java.io.FileOutputStream ;  
  7. public class ZipOutputStreamDemo01{  
  8.     public static void main(String args[]) throws Exception{    // 所有异常抛出  
  9.         File file = new File("d:" + File.separator + "mldn.txt") ;  // 定义要压缩的文件  
  10.         File zipFile = new File("d:" + File.separator + "mldn.zip") ;   // 定义压缩文件名称  
  11.         InputStream input = new FileInputStream(file) ; // 定义文件的输入流  
  12.         ZipOutputStream zipOut = null ; // 声明压缩流对象  
  13.         zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;  
  14.         zipOut.putNextEntry(new ZipEntry(file.getName())) ; // 设置ZipEntry对象  
  15.         zipOut.setComment("www.mldnjava.cn") ;  // 设置注释  
  16.         int temp = 0 ;  
  17.         while((temp=input.read())!=-1){ // 读取内容  
  18.             zipOut.write(temp) ;    // 压缩输出  
  19.         }  
  20.         input.close() ; // 关闭输入流  
  21.         zipOut.close() ;    // 关闭输出流  
  22.     }  
  23. };  
以上的操作代码完成的只是一个文件的压缩,如果要完成一个文件夹呢?

Java IO 压缩流(ZipOutputStream/ZipInputStream)

  1. import java.io.File ;  
  2. import java.io.FileInputStream ;  
  3. import java.io.InputStream ;  
  4. import java.util.zip.ZipEntry ;  
  5. import java.util.zip.ZipOutputStream ;  
  6. import java.io.FileOutputStream ;  
  7. public class ZipOutputStreamDemo02{  
  8.     public static void main(String args[]) throws Exception{    // 所有异常抛出  
  9.         File file = new File("d:" + File.separator + "mldn") ;  // 定义要压缩的文件夹  
  10.         File zipFile = new File("d:" + File.separator + "mldndir.zip") ;    // 定义压缩文件名称  
  11.         InputStream input = null ;  // 定义文件输入流  
  12.         ZipOutputStream zipOut = null ; // 声明压缩流对象  
  13.         zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;  
  14.         zipOut.setComment("www.mldnjava.cn") ;  // 设置注释  
  15.         int temp = 0 ;  
  16.         if(file.isDirectory()){ // 判断是否是文件夹  
  17.             File lists[] = file.listFiles() ;   // 列出全部文件  
  18.             for(int i=0;i<lists.length;i++){  
  19.                 input = new FileInputStream(lists[i]) ; // 定义文件的输入流  
  20.                 zipOut.putNextEntry(new ZipEntry(file.getName()  
  21.                     +File.separator+lists[i].getName())) ;  // 设置ZipEntry对象  
  22.                 while((temp=input.read())!=-1){ // 读取内容  
  23.                     zipOut.write(temp) ;    // 压缩输出  
  24.                 }  
  25.                 input.close() ; // 关闭输入流  
  26.             }  
  27.         }  
  28.         zipOut.close() ;    // 关闭输出流  
  29.     }  
  30. };  
3.2 ZipFile

是一个专门表示压缩文件的类。
Java IO 压缩流(ZipOutputStream/ZipInputStream)

ZipFile 在实例化的时候必须接收File 类的实例。此File 类的实例是指向一个压缩 *.zip 文件。

第一步:为 ZipFile 实例

1. 实例化时需要接收File  类的引用

  1. import java.io.File ;  
  2. import java.io.FileInputStream ;  
  3. import java.io.InputStream ;  
  4. import java.util.zip.ZipEntry ;  
  5. import java.util.zip.ZipOutputStream ;  
  6. import java.util.zip.ZipFile ;  
  7. import java.io.FileOutputStream ;  
  8. public class ZipFileDemo01{  
  9.     public static void main(String args[]) throws Exception{    // 所有异常抛出  
  10.         File file = new File("d:" + File.separator + "mldn.zip") ;  // 找到压缩文件  
  11.         ZipFile zipFile = new ZipFile(file) ;   // 实例化ZipFile对象  
  12.         System.out.println("压缩文件的名称:" + zipFile.getName()) ;    // 得到压缩文件的名称  
  13.     }  
  14. };  

2. 通过ZipFile 文件,为mldn.zip 进行解压缩操作。

  1. import java.io.File ;  
  2. import java.io.FileInputStream ;  
  3. import java.io.InputStream ;  
  4. import java.util.zip.ZipEntry ;  
  5. import java.util.zip.ZipOutputStream ;  
  6. import java.io.FileOutputStream ;  
  7. public class ZipOutputStreamDemo02{  
  8.     public static void main(String args[]) throws Exception{    // 所有异常抛出  
  9.         File file = new File("d:" + File.separator + "mldn") ;  // 定义要压缩的文件夹  
  10.         File zipFile = new File("d:" + File.separator + "mldndir.zip") ;    // 定义压缩文件名称  
  11.         InputStream input = null ;  // 定义文件输入流  
  12.         ZipOutputStream zipOut = null ; // 声明压缩流对象  
  13.         zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;  
  14.         zipOut.setComment("www.mldnjava.cn") ;  // 设置注释  
  15.         int temp = 0 ;  
  16.         if(file.isDirectory()){ // 判断是否是文件夹  
  17.             File lists[] = file.listFiles() ;   // 列出全部文件  
  18.             for(int i=0;i<lists.length;i++){  
  19.                 input = new FileInputStream(lists[i]) ; // 定义文件的输入流  
  20.                 zipOut.putNextEntry(new ZipEntry(file.getName()  
  21.                     +File.separator+lists[i].getName())) ;  // 设置ZipEntry对象  
  22.                 while((temp=input.read())!=-1){ // 读取内容  
  23.                     zipOut.write(temp) ;    // 压缩输出  
  24.                 }  
  25.                 input.close() ; // 关闭输入流  
  26.             }  
  27.         }  
  28.         zipOut.close() ;    // 关闭输出流  
  29.     }  
  30. };  
以上的操作中,有一个问题,必须知道压缩文件中的每一个压缩实体的名称才可以进行解压缩操作,而如果现在在假设是一个文件夹呢? 
3、利用ZipInputStream读取zip

定义:

java.lang.Object
  java.io.InputStream
      java.io.FilterInputStream
          java.util.zip.InflaterInputStream
              java.util.zip.ZipInputStream
  1. import java.io.File ;  
  2. import java.io.FileInputStream ;  
  3. import java.io.InputStream ;  
  4. import java.util.zip.ZipEntry ;  
  5. import java.util.zip.ZipInputStream ;  
  6. import java.io.FileInputStream ;  
  7. public class ZipInputStreamDemo01{  
  8.     public static void main(String args[]) throws Exception{    // 所有异常抛出  
  9.         File zipFile = new File("d:" + File.separator + "mldn.zip") ;   // 定义压缩文件名称  
  10.         ZipInputStream input = null ;   // 定义压缩输入流  
  11.         input = new ZipInputStream(new FileInputStream(zipFile)) ;  // 实例化ZIpInputStream  
  12.         ZipEntry entry = input.getNextEntry() ; // 得到一个压缩实体  
  13.         System.out.println("压缩实体名称:" + entry.getName()) ;  
  14.         input.close() ;  
  15.     }  
  16. };  
利用此特性并结合 ZipFile 就可以完成解压缩文件夹的功能。

ZipFile 对象,可以找到每一个ZipEntry 的输入流。但是ZipInputStream 并不能得到每一个输入流,所以需要使用ZipFile,但是ZipInputStream  在取得每一个ZipEntry 的时候,不需要每一个ZipEntry 的时候,不需要每一个ZipEntry 的名称。

  1. import java.io.File ;  
  2. import java.io.OutputStream ;  
  3. import java.io.InputStream ;  
  4. import java.util.zip.ZipEntry ;  
  5. import java.util.zip.ZipFile ;  
  6. import java.util.zip.ZipInputStream ;  
  7. import java.io.FileInputStream ;  
  8. import java.io.FileOutputStream ;  
  9. public class ZipInputStreamDemo02{  
  10.     public static void main(String args[]) throws Exception{    // 所有异常抛出  
  11.         File file = new File("d:" + File.separator + "mldndir.zip") ;   // 定义压缩文件名称  
  12.         File outFile = null ;   // 输出文件的时候要有文件夹的操作  
  13.         ZipFile zipFile = new ZipFile(file) ;   // 实例化ZipFile对象  
  14.         ZipInputStream zipInput = null ;    // 定义压缩输入流  
  15.         OutputStream out = null ;   // 定义输出流,用于输出每一个实体内容  
  16.         InputStream input = null ;  // 定义输入流,读取每一个ZipEntry  
  17.         ZipEntry entry = null ; // 每一个压缩实体  
  18.         zipInput = new ZipInputStream(new FileInputStream(file)) ;  // 实例化ZIpInputStream  
  19.         while((entry = zipInput.getNextEntry())!=null){ // 得到一个压缩实体  
  20.             System.out.println("解压缩" + entry.getName() + "文件。") ;  
  21.             outFile = new File("d:" + File.separator + entry.getName()) ;   // 定义输出的文件路径  
  22.             if(!outFile.getParentFile().exists()){  // 如果输出文件夹不存在
  23.                 outFile.getParentFile().mkdir() ;   // 创建文件夹 ,如果这里的有多个文件夹不存在,请使用mkdirs(),如果只是单纯的一个文件夹,使用mkdir()就好了
  24.             }  
  25.             if(!outFile.exists()){  // 判断输出文件是否存在  
  26.                 outFile.createNewFile() ;   // 创建文件  
  27.             }  
  28.             input = zipFile.getInputStream(entry) ; // 得到每一个实体的输入流  
  29.             out = new FileOutputStream(outFile) ;   // 实例化文件输出流  
  30.             int temp = 0 ;  
  31.             while((temp=input.read())!=-1){  
  32.                 out.write(temp) ;  
  33.             }  
  34.             input.close() ;     // 关闭输入流  
  35.             out.close() ;   // 关闭输出流  
  36.         }  
  37.         input.close() ;  
  38.     }  
  39. };  
如果目录不存在,则应该进行创建操作。

总结:

1、压缩文件中的每一个压缩实体都使用ZipEntry 保存,一个压缩文件中可能包含一个或多个的ZipEntry 对象。

2、在JAVA中可以进行zip、jar、gz、三种格式的压缩支持,操作流程基本上是一样的

3、ZipOutputStream 可以进行压缩输出,但是输出的位置不一定是文件。

4、ZipFile 表示每一个压缩文件,可以得到每一个压缩实体的输入流

5、ZipInputStream 可以得到每一个实体,但是却无法得到每一个实体的输入流。

6.  JDK中的ZipInputStream与ZipOutputStream 在压缩与解压缩操作中容易出现乱码,建议大家使用Apache的ZipInputStream与ZipOutputStream,因为它可以设置字 

     符编码charset,这样就能够保证在写入/读取文件时,最大限度的避免乱码问题的发生!