从ZIP文件中解压缩和提取数据

来源:互联网 发布:罗技鼠标mac用法 编辑:程序博客网 时间:2024/05/16 06:53

从ZIP文件中解压缩和提取数据


 
 
 
 

java.util.zip包提供了数据压缩与解压缩所需要的类。ZIP文件的解压缩实质上就是从输入流中读取数据。Java.util.zip包提供了类ZipInputStream来读取ZIP文件。ZipInputStream流的创建与其它输入流的创建没什么两样。举个例子,下面的代码段创建了一个输入流来读取ZIP格式的文件:

FileInputStream fis = new FileInputStream("figs.zip");ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis));


ZIP输入流打开后,你可以使用getNextEntry方法来读取ZIP文件中的条目数,该方法返回一个ZipEntry对象。如果到达文件的尾部,getNextEntry返回null:

ZipEntry entry;while((entry = zin.getNextEntry()) != null) {    // extract data    // open output streams}


现在,你应该建立一个输出流,如下所示:

int BUFFER = 2048;FileOutputStream fos = new FileOutputStream(entry.getName());BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);


注意:在这段代码中我们用BufferedOutputStream代替了ZIPOutputStream。ZIPOutputStream和GZIPOutputStream使用内置的512字节缓冲。当缓冲区的大小大于512字节时,使用BufferedOutputStream才是正确的(例子中设置为2048)。ZIPOutputStream不允许你设置缓冲区的大小,GZIPOutputStream也是一样,但创建 GZIPOutputStream 对象时可以通过构造函数的参数指定内置的缓冲尺寸。

这段代码中,使用ZIP内含的条目名称创建一个文件输出流。可以使用entry.getName来得到它的返回句柄。接着读出被压缩的源数据,然后写入输出流:

while ((count = zin.read(data, 0, BUFFER)) != -1) {    //System.out.write(x);    dest.write(data, 0, count);}


最后,不要忘记关闭输入和输出流:

dest.flush();dest.close();zin.close();


例程1的源程序UnZip.java显示如何解压缩并从ZIP档案中将文件释放出来。测试这个例子,编译这个类,并运行它,传给它一个ZIP格式的文件作为参数:

prompt> java UnZip somefile.zip

注意:somefile.zip应该是一个ZIP压缩档案,可以用任何一种ZIP压缩工具来创建,例如WinZip。

例程1源代码:

UnZip.javaimport java.io.*;import java.util.zip.*;public class UnZip {    static final int BUFFER = 2048;   //16384
    public static void main (String argv[]) {       try {          BufferedOutputStream dest = null;          FileInputStream fis = new         FileInputStream(argv[0]);          ZipInputStream zis = new         ZipInputStream(new BufferedInputStream(fis));          ZipEntry entry;          while((entry = zis.getNextEntry()) != null) {             System.out.println("Extracting: " +entry);             int count;             byte data[] = new byte[BUFFER];             // write the files to the disk             FileOutputStream fos = new            FileOutputStream(entry.getName());             dest = new                BufferedOutputStream(fos, BUFFER);             while ((count = zis.read(data, 0, BUFFER))                != -1) {                dest.write(data, 0, count);             }             dest.flush();             dest.close();          }          zis.close();       } catch(Exception e) {          e.printStackTrace();       }    }}


有一点值得大家注意,类ZipInputStream读出ZIP文件序列(简单地说就是读出这个ZIP文件压缩了多少文件),而类ZipFile使用内嵌的随机文件访问机制读出其中的文件内容,所以不必顺序的读出ZIP压缩文件序列。

注意:ZIPInputStream和ZipFile之间另外一个基本的不同点在于高速缓冲的使用方面。当文件使用ZipInputStream和FileInputStream流读出的时候,ZIP条目不使用高速缓冲。然而,如果使用ZipFile(文件名)来打开文件,它将使用内嵌的高速缓冲,所以如果ZipFile(文件名)被重复调用的话,文件只被打开一次。缓冲值在第二次打开进使用。如果你工作在UNIX系统下,这是什么作用都没有的,因为使用ZipFile打开的所有ZIP文件都在内存中存在映射,所以使用ZipFile的性能优于ZipInputStream。然而,如果同一ZIP文件的内容在程序执行期间经常改变,或是重载的话,使用ZipInputStream就成为你的首选了。

下面显示了使用类ZipFile来解压一个ZIP文件的过程:

  1. 通过指定一个被读取的ZIP文件,或者是文件名,或者是一个文件对象来创建一个ZipFile对象:
    ZipFile zipfile = new ZipFile("figs.zip");

  2. 使用entries方法,返回一个枚举对象,循环获得文件的ZIP条目对象:
    while(e.hasMoreElements()) {
    entry = (ZipEntry) e.nextElement();
    // read contents and save them
    }

  3. ZIP条目作为参数传递给getInputStream方法,可以读取ZIP文件中指定条目的内容,能过其返回的输入流(InputStram)对象可以方便的读出ZIP条目的内容:
    is = new BufferedInputStream(zipfile.getInputStream(entry));

  4. 获取ZIP条目的文件名,创建输出流,并保存:
    byte data[] = new byte[BUFFER];
    FileOutputStream fos = new FileOutputStream(entry.getName());
    dest = new BufferedOutputStream(fos, BUFFER);
    while ((count = is.read(data, 0, BUFFER)) != -1) {
    dest.write(data, 0, count);
    }

  5. 最后关闭所有的输入输出流 dest.flush();
    dest.close();
    is.close();

完整的程序代码如例程2所示。再次编译这个文件,并传递一个ZIP格式的文件做为参数:

prompt> java UnZip2 somefile.zip

例程2源码:

UnZip2.java import java.io.*;import java.util.*;import java.util.zip.*;public class UnZip2 {    static final int BUFFER = 2048;    public static void main (String argv[]) {       try {          BufferedOutputStream dest = null;          BufferedInputStream is = null;          ZipEntry entry;          ZipFile zipfile = new ZipFile(argv[0]);          Enumeration e = zipfile.entries();          while(e.hasMoreElements()) {             entry = (ZipEntry) e.nextElement();             System.out.println("Extracting: " +entry);             is = new BufferedInputStream               (zipfile.getInputStream(entry));             int count;             byte data[] = new byte[BUFFER];             FileOutputStream fos = new                FileOutputStream(entry.getName());             dest = new                BufferedOutputStream(fos, BUFFER);             while ((count = is.read(data, 0, BUFFER))                != -1) {                dest.write(data, 0, count);             }             dest.flush();             dest.close();             is.close();          }       } catch(Exception e) {          e.printStackTrace();       }    }}
转转:
http://www.cnblogs.com/zhang-qiang/articles/2051499.html
原创粉丝点击