欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java解压zip文件示例

程序员文章站 2024-02-23 11:29:22
若是使用java自带的压缩工具包来实现解压缩文件到指定文件夹的功能,因为jdk提供的zip只能按utf-8格式处理,而windows系统中文件名是以gbk方式编码的,所以如...

若是使用java自带的压缩工具包来实现解压缩文件到指定文件夹的功能,因为jdk提供的zip只能按utf-8格式处理,而windows系统中文件名是以gbk方式编码的,所以如果是解压一个包含中文文件名的zip包,会报非法参数异常,所以要实现解压缩,就得对deflateroutputstream.java、inflaterinputstream.java、zipconstants.java、zipentry.java、zipinputstream.java以及zipoutputstream.java这些相关的类进行修改,过程如下:
因为从 j2se 1.4 开始,java 编译器不再支持 import 进未命包名的类、接口,所以在创建的java项目中,一定要新建一个自己定义的包,包命名的格式一般为学校域名的逆序+自己的网名,比如cn.edu.xidian.crytoll。
在包内新建deflateroutputstream类,代码如下:

deflateroutputstream.java:

复制代码 代码如下:

package cn.edu.xdian.crytoll;

import java.io.filteroutputstream;
import java.io.ioexception;
import java.io.outputstream;
import java.util.zip.deflater;

/**
 * this class implements an output stream filter for compressing data in
 * the "deflate" compression format. it is also used as the basis for other
 * types of compression filters, such as gzipoutputstream.
 *
 * @see     deflater
 * @version     1.36, 03/13/06
 * @author  david connelly
 */
public
class deflateroutputstream extends filteroutputstream {
    /**
     * compressor for this stream.
     */
    protected deflater def;

    /**
     * output buffer for writing compressed data.
     */
    protected byte[] buf;

    /**
     * indicates that the stream has been closed.
     */

    private boolean closed = false;

    /**
     * creates a new output stream with the specified compressor and
     * buffer size.
     * @param out the output stream
     * @param def the compressor ("deflater")
     * @param size the output buffer size
     * @exception illegalargumentexception if size is <= 0
     */
    public deflateroutputstream(outputstream out, deflater def, int size) {
        super(out);
        if (out == null || def == null) {
            throw new nullpointerexception();
        } else if (size <= 0) {
            throw new illegalargumentexception("buffer size <= 0");
        }
        this.def = def;
        buf = new byte[size];
    }

    /**
     * creates a new output stream with the specified compressor and
     * a default buffer size.
     * @param out the output stream
     * @param def the compressor ("deflater")
     */
    public deflateroutputstream(outputstream out, deflater def) {
    this(out, def, 512);
    }

    boolean usesdefaultdeflater = false;

    /**
     * creates a new output stream with a default compressor and buffer size.
     * @param out the output stream
     */
    public deflateroutputstream(outputstream out) {
    this(out, new deflater());
        usesdefaultdeflater = true;
    }

    /**
     * writes a byte to the compressed output stream. this method will
     * block until the byte can be written.
     * @param b the byte to be written
     * @exception ioexception if an i/o error has occurred
     */
    public void write(int b) throws ioexception {
        byte[] buf = new byte[1];
    buf[0] = (byte)(b & 0xff);
    write(buf, 0, 1);
    }

    /**
     * writes an array of bytes to the compressed output stream. this
     * method will block until all the bytes are written.
     * @param b the data to be written
     * @param off the start offset of the data
     * @param len the length of the data
     * @exception ioexception if an i/o error has occurred
     */
    public void write(byte[] b, int off, int len) throws ioexception {
    if (def.finished()) {
        throw new ioexception("write beyond end of stream");
    }
        if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
        throw new indexoutofboundsexception();
    } else if (len == 0) {
        return;
    }
    if (!def.finished()) {
            // deflate no more than stride bytes at a time.  this avoids
            // excess copying in deflatebytes (see deflater.c)
            int stride = buf.length;
            for (int i = 0; i < len; i+= stride) {
                def.setinput(b, off + i, math.min(stride, len - i));
                while (!def.needsinput()) {
                    deflate();
                }
            }
    }
    }

    /**
     * finishes writing compressed data to the output stream without closing
     * the underlying stream. use this method when applying multiple filters
     * in succession to the same output stream.
     * @exception ioexception if an i/o error has occurred
     */
    public void finish() throws ioexception {
    if (!def.finished()) {
        def.finish();
        while (!def.finished()) {
        deflate();
        }
    }
    }

    /**
     * writes remaining compressed data to the output stream and closes the
     * underlying stream.
     * @exception ioexception if an i/o error has occurred
     */
    public void close() throws ioexception {
        if (!closed) {
            finish();
            if (usesdefaultdeflater)
                def.end();
            out.close();
            closed = true;
        }
    }

    /**
     * writes next block of compressed data to the output stream.
     * @throws ioexception if an i/o error has occurred
     */
    protected void deflate() throws ioexception {
    int len = def.deflate(buf, 0, buf.length);
    if (len > 0) {
        out.write(buf, 0, len);
    }
    }
}