本文使用了jdk1.5.0_13的源代码。(java.uti.zip*)
实现方法:首先将java.uti.zip中的源代码解压出来。找到DeflaterOutputStream、InflaterInputStream、ZipConstants、ZipEntry、ZipInputStream、ZipOutputStream,放到新的包com.work.util.zip中,重新组织这些文件的import,能使用当前包中类的就使用当前包中的类。
重点要修改的类:ZipEntry,修改内容如下:
- //修改对应的程序,在这里加载zip库
- static {
- /* load the zip library */
- java.security.AccessController
- .doPrivileged(new sun.security.action.LoadLibraryAction("zip"));
- // initIDs();
- }
- // static {
- // /* Zip library is loaded from System.initializeSystemClass */
- // initIDs();
- // }
- // private static native void initIDs();
其次修改ZipInputStream,大约在279行。
- // ZipEntry e = createZipEntry(getUTF8String(b, 0, len));
- ZipEntry e = null;
- try {
- if (this.encoding.toUpperCase().equals("UTF-8"))
- e = createZipEntry(getUTF8String(b, 0, len));
- else
- e = createZipEntry(new String(b, 0, len, this.encoding));
- } catch (Exception byteE) {
- e = createZipEntry(getUTF8String(b, 0, len));
- }
- //增加构造方法
- private String encoding = "UTF-8";
- public ZipInputStream(InputStream in, String encoding) {
super(new PushbackInputStream(in, 512), new Inflater(true), 512);
usesDefaultInflater = true;
if (in == null) {
throw new NullPointerException("in is null");
}
this.encoding = encoding;
}
再次修改ZipOutputStream类,源代码如下:
- /*
- * @(#)ZipOutputStream.java 1.31 03/12/19
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- package com.work.util.zip;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.Enumeration;
- import java.util.Hashtable;
- import java.util.Vector;
- import java.util.zip.CRC32;
- import java.util.zip.Deflater;
- import java.util.zip.ZipException;
- /**
- * This class implements an output stream filter for writing files in the ZIP
- * file format. Includes support for both compressed and uncompressed entries.
- *
- * @author David Connelly
- * @version 1.31, 12/19/03
- */
- public class ZipOutputStream extends DeflaterOutputStream implements
- ZipConstants {
- private ZipEntry entry;
- private Vector entries = new Vector();
- private Hashtable names = new Hashtable();
- private CRC32 crc = new CRC32();
- private long written = 0;
- private long locoff = 0;
- private String comment;
- private int method = DEFLATED;
- private boolean finished;
- private boolean closed = false;
- /**
- * Check to make sure that this stream has not been closed
- */
- private void ensureOpen() throws IOException {
- if (closed) {
- throw new IOException("Stream closed");
- }
- }
- /**
- * Compression method for uncompressed (STORED) entries.
- */
- public static final int STORED = ZipEntry.STORED;
- /**
- * Compression method for compressed (DEFLATED) entries.
- */
- public static final int DEFLATED = ZipEntry.DEFLATED;
- private String encoding = "UTF-8";
- public ZipOutputStream(OutputStream out, String encoding) {
- super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
- usesDefaultDeflater = true;
- this.encoding = encoding;
- }
- /**
- * Creates a new ZIP output stream.
- *
- * @param out
- * the actual output stream
- */
- public ZipOutputStream(OutputStream out) {
- super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
- usesDefaultDeflater = true;
- }
- /**
- * Sets the ZIP file comment.
- *
- * @param comment
- * the comment string
- * @exception IllegalArgumentException
- * if the length of the specified ZIP file comment is greater
- * than 0xFFFF bytes
- */
- public void setComment(String comment) {
- if (comment != null && comment.length() > 0xffff / 3
- && getUTF8Length(comment) > 0xffff) {
- throw new IllegalArgumentException("ZIP file comment too long.");
- }
- this.comment = comment;
- }
- /**
- * Sets the default compression method for subsequent entries. This default
- * will be used whenever the compression method is not specified for an
- * individual ZIP file entry, and is initially set to DEFLATED.
- *
- * @param method
- * the default compression method
- * @exception IllegalArgumentException
- * if the specified compression method is invalid
- */
- public void setMethod(int method) {
- if (method != DEFLATED && method != STORED) {
- throw new IllegalArgumentException("invalid compression method");
- }
- this.method = method;
- }
- /**
- * Sets the compression level for subsequent entries which are DEFLATED. The
- * default setting is DEFAULT_COMPRESSION.
- *
- * @param level
- * the compression level (0-9)
- * @exception IllegalArgumentException
- * if the compression level is invalid
- */
- public void setLevel(int level) {
- def.setLevel(level);
- }
- /**
- * Begins writing a new ZIP file entry and positions the stream to the start
- * of the entry data. Closes the current entry if still active. The default
- * compression method will be used if no compression method was specified
- * for the entry, and the current time will be used if the entry has no set
- * modification time.
- *
- * @param e
- * the ZIP entry to be written
- * @exception ZipException
- * if a ZIP format error has occurred
- * @exception IOException
- * if an I/O error has occurred
- */
- public void putNextEntry(ZipEntry e) throws IOException {
- ensureOpen();
- if (entry != null) {
- closeEntry(); // close previous entry
- }
- if (e.time == -1) {
- e.setTime(System.currentTimeMillis());
- }
- if (e.method == -1) {
- e.method = method; // use default method
- }
- switch (e.method) {
- case DEFLATED:
- if (e.size == -1 || e.csize == -1 || e.crc == -1) {
- // store size, compressed size, and crc-32 in data descriptor
- // immediately following the compressed entry data
- e.flag = 8;
- } else if (e.size != -1 && e.csize != -1 && e.crc != -1) {
- // store size, compressed size, and crc-32 in LOC header
- e.flag = 0;
- } else {
- throw new ZipException(
- "DEFLATED entry missing size, compressed size, or crc-32");
- }
- e.version = 20;
- break;
- case STORED:
- // compressed size, uncompressed size, and crc-32 must all be
- // set for entries using STORED compression method
- if (e.size == -1) {
- e.size = e.csize;
- } else if (e.csize == -1) {
- e.csize = e.size;
- } else if (e.size != e.csize) {
- throw new ZipException(
- "STORED entry where compressed != uncompressed size");
- }
- if (e.size == -1 || e.crc == -1) {
- throw new ZipException(
- "STORED entry missing size, compressed size, or crc-32");
- }
- e.version = 10;
- e.flag = 0;
- break;
- default:
- throw new ZipException("unsupported compression method");
- }
- e.offset = written;
- if (names.put(e.name, e) != null) {
- throw new ZipException("duplicate entry: " + e.name);
- }
- writeLOC(e);
- entries.addElement(e);
- entry = e;
- }
- /**
- * Closes the current ZIP entry and positions the stream for writing the
- * next entry.
- *
- * @exception ZipException
- * if a ZIP format error has occurred
- * @exception IOException
- * if an I/O error has occurred
- */
- public void closeEntry() throws IOException {
- ensureOpen();
- ZipEntry e = entry;
- if (e != null) {
- switch (e.method) {
- case DEFLATED:
- def.finish();
- while (!def.finished()) {
- deflate();
- }
- if ((e.flag & 8) == 0) {
- // verify size, compressed size, and crc-32 settings
- if (e.size != def.getBytesRead()) {
- throw new ZipException("invalid entry size (expected "
- + e.size + " but got " + def.getBytesRead()
- + " bytes)");
- }
- if (e.csize != def.getBytesWritten()) {
- throw new ZipException(
- "invalid entry compressed size (expected "
- + e.csize + " but got "
- + def.getBytesWritten() + " bytes)");
- }
- if (e.crc != crc.getValue()) {
- throw new ZipException(
- "invalid entry CRC-32 (expected 0x"
- + Long.toHexString(e.crc)
- + " but got 0x"
- + Long.toHexString(crc.getValue())
- + ")");
- }
- } else {
- e.size = def.getBytesRead();
- e.csize = def.getBytesWritten();
- e.crc = crc.getValue();
- writeEXT(e);
- }
- def.reset();
- written += e.csize;
- break;
- case STORED:
- // we already know that both e.size and e.csize are the same
- if (e.size != written - locoff) {
- throw new ZipException("invalid entry size (expected "
- + e.size + " but got " + (written - locoff)
- + " bytes)");
- }
- if (e.crc != crc.getValue()) {
- throw new ZipException("invalid entry crc-32 (expected 0x"
- + Long.toHexString(e.crc) + " but got 0x"
- + Long.toHexString(crc.getValue()) + ")");
- }
- break;
- default:
- throw new InternalError("invalid compression method");
- }
- crc.reset();
- entry = null;
- }
- }
- /**
- * Writes an array of bytes to the current ZIP entry data. This method will
- * block until all the bytes are written.
- *
- * @param b
- * the data to be written
- * @param off
- * the start offset in the data
- * @param len
- * the number of bytes that are written
- * @exception ZipException
- * if a ZIP file error has occurred
- * @exception IOException
- * if an I/O error has occurred
- */
- public synchronized void write(byte[] b, int off, int len)
- throws IOException {
- ensureOpen();
- if (off < 0 || len < 0 || off > b.length - len) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return;
- }
- if (entry == null) {
- throw new ZipException("no current ZIP entry");
- }
- switch (entry.method) {
- case DEFLATED:
- super.write(b, off, len);
- break;
- case STORED:
- written += len;
- if (written - locoff > entry.size) {
- throw new ZipException(
- "attempt to write past end of STORED entry");
- }
- out.write(b, off, len);
- break;
- default:
- throw new InternalError("invalid compression method");
- }
- crc.update(b, off, len);
- }
- /**
- * Finishes writing the contents of the ZIP output stream without closing
- * the underlying stream. Use this method when applying multiple filters in
- * succession to the same output stream.
- *
- * @exception ZipException
- * if a ZIP file error has occurred
- * @exception IOException
- * if an I/O exception has occurred
- */
- public void finish() throws IOException {
- ensureOpen();
- if (finished) {
- return;
- }
- if (entry != null) {
- closeEntry();
- }
- if (entries.size() < 1) {
- throw new ZipException("ZIP file must have at least one entry");
- }
- // write central directory
- long off = written;
- Enumeration e = entries.elements();
- while (e.hasMoreElements()) {
- writeCEN((ZipEntry) e.nextElement());
- }
- writeEND(off, written - off);
- finished = true;
- }
- /**
- * Closes the ZIP output stream as well as the stream being filtered.
- *
- * @exception ZipException
- * if a ZIP file error has occurred
- * @exception IOException
- * if an I/O error has occurred
- */
- public void close() throws IOException {
- if (!closed) {
- super.close();
- closed = true;
- }
- }
- /*
- * Writes local file (LOC) header for specified entry.
- */
- private void writeLOC(ZipEntry e) throws IOException {
- writeInt(LOCSIG); // LOC header signature
- writeShort(e.version); // version needed to extract
- writeShort(e.flag); // general purpose bit flag
- writeShort(e.method); // compression method
- writeInt(e.time); // last modification time
- if ((e.flag & 8) == 8) {
- // store size, uncompressed size, and crc-32 in data descriptor
- // immediately following compressed entry data
- writeInt(0);
- writeInt(0);
- writeInt(0);
- } else {
- writeInt(e.crc); // crc-32
- writeInt(e.csize); // compressed size
- writeInt(e.size); // uncompressed size
- }
- // byte[] nameBytes = getUTF8Bytes(e.name);
- byte[] nameBytes = null;
- try {
- if (this.encoding.toUpperCase().equals("UTF-8"))
- nameBytes = getUTF8Bytes(e.name);
- else
- nameBytes = e.name.getBytes(this.encoding);
- } catch (Exception byteE) {
- nameBytes = getUTF8Bytes(e.name);
- }
- writeShort(nameBytes.length);
- writeShort(e.extra != null ? e.extra.length : 0);
- writeBytes(nameBytes, 0, nameBytes.length);
- if (e.extra != null) {
- writeBytes(e.extra, 0, e.extra.length);
- }
- locoff = written;
- }
- /*
- * Writes extra data descriptor (EXT) for specified entry.
- */
- private void writeEXT(ZipEntry e) throws IOException {
- writeInt(EXTSIG); // EXT header signature
- writeInt(e.crc); // crc-32
- writeInt(e.csize); // compressed size
- writeInt(e.size); // uncompressed size
- }
- /*
- * Write central directory (CEN) header for specified entry. REMIND: add
- * support for file attributes
- */
- private void writeCEN(ZipEntry e) throws IOException {
- writeInt(CENSIG); // CEN header signature
- writeShort(e.version); // version made by
- writeShort(e.version); // version needed to extract
- writeShort(e.flag); // general purpose bit flag
- writeShort(e.method); // compression method
- writeInt(e.time); // last modification time
- writeInt(e.crc); // crc-32
- writeInt(e.csize); // compressed size
- writeInt(e.size); // uncompressed size
- // byte[] nameBytes = getUTF8Bytes(e.name);
- byte[] nameBytes = null;
- try {
- if (this.encoding.toUpperCase().equals("UTF-8"))
- nameBytes = getUTF8Bytes(e.name);
- else
- nameBytes = e.name.getBytes(this.encoding);
- } catch (Exception byteE) {
- nameBytes = getUTF8Bytes(e.name);
- }
- writeShort(nameBytes.length);
- writeShort(e.extra != null ? e.extra.length : 0);
- byte[] commentBytes;
- if (e.comment != null) {
- //commentBytes = getUTF8Bytes(e.comment);
- try {
- if (this.encoding.toUpperCase().equals("UTF-8"))
- commentBytes = getUTF8Bytes(e.comment);
- else
- commentBytes = e.comment.getBytes(this.encoding);
- } catch (Exception byteE) {
- commentBytes = getUTF8Bytes(e.comment);
- }
- writeShort(commentBytes.length);
- } else {
- commentBytes = null;
- writeShort(0);
- }
- writeShort(0); // starting disk number
- writeShort(0); // internal file attributes (unused)
- writeInt(0); // external file attributes (unused)
- writeInt(e.offset); // relative offset of local header
- writeBytes(nameBytes, 0, nameBytes.length);
- if (e.extra != null) {
- writeBytes(e.extra, 0, e.extra.length);
- }
- if (commentBytes != null) {
- writeBytes(commentBytes, 0, commentBytes.length);
- }
- }
- /*
- * Writes end of central directory (END) header.
- */
- private void writeEND(long off, long len) throws IOException {
- writeInt(ENDSIG); // END record signature
- writeShort(0); // number of this disk
- writeShort(0); // central directory start disk
- writeShort(entries.size()); // number of directory entries on disk
- writeShort(entries.size()); // total number of directory entries
- writeInt(len); // length of central directory
- writeInt(off); // offset of central directory
- if (comment != null) { // zip file comment
- //byte[] b = getUTF8Bytes(comment);
- byte[] b = null;
- try {
- if (this.encoding.toUpperCase().equals("UTF-8"))
- b = getUTF8Bytes(comment);
- else
- b = comment.getBytes(this.encoding);
- } catch (Exception byteE) {
- b = getUTF8Bytes(comment);
- }
- writeShort(b.length);
- writeBytes(b, 0, b.length);
- } else {
- writeShort(0);
- }
- }
- /*
- * Writes a 16-bit short to the output stream in little-endian byte order.
- */
- private void writeShort(int v) throws IOException {
- OutputStream out = this.out;
- out.write((v >>> 0) & 0xff);
- out.write((v >>> 8) & 0xff);
- written += 2;
- }
- /*
- * Writes a 32-bit int to the output stream in little-endian byte order.
- */
- private void writeInt(long v) throws IOException {
- OutputStream out = this.out;
- out.write((int) ((v >>> 0) & 0xff));
- out.write((int) ((v >>> 8) & 0xff));
- out.write((int) ((v >>> 16) & 0xff));
- out.write((int) ((v >>> 24) & 0xff));
- written += 4;
- }
- /*
- * Writes an array of bytes to the output stream.
- */
- private void writeBytes(byte[] b, int off, int len) throws IOException {
- super.out.write(b, off, len);
- written += len;
- }
- /*
- * Returns the length of String's UTF8 encoding.
- */
- static int getUTF8Length(String s) {
- int count = 0;
- for (int i = 0; i < s.length(); i++) {
- char ch = s.charAt(i);
- if (ch <= 0x7f) {
- count++;
- } else if (ch <= 0x7ff) {
- count += 2;
- } else {
- count += 3;
- }
- }
- return count;
- }
- /*
- * Returns an array of bytes representing the UTF8 encoding of the specified
- * String.
- */
- private static byte[] getUTF8Bytes(String s) {
- char[] c = s.toCharArray();
- int len = c.length;
- // Count the number of encoded bytes...
- int count = 0;
- for (int i = 0; i < len; i++) {
- int ch = c[i];
- if (ch <= 0x7f) {
- count++;
- } else if (ch <= 0x7ff) {
- count += 2;
- } else {
- count += 3;
- }
- }
- // Now return the encoded bytes...
- byte[] b = new byte[count];
- int off = 0;
- for (int i = 0; i < len; i++) {
- int ch = c[i];
- if (ch <= 0x7f) {
- b[off++] = (byte) ch;
- } else if (ch <= 0x7ff) {
- b[off++] = (byte) ((ch >> 6) | 0xc0);
- b[off++] = (byte) ((ch & 0x3f) | 0x80);
- } else {
- b[off++] = (byte) ((ch >> 12) | 0xe0);
- b[off++] = (byte) (((ch >> 6) & 0x3f) | 0x80);
- b[off++] = (byte) ((ch & 0x3f) | 0x80);
- }
- }
- return b;
- }
- }
剩下的工作就是编写压缩和解压缩的功能类了ZipUtil.java
- package com.work.util;
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import com.work.util.zip.ZipInputStream;
- import com.work.util.zip.ZipOutputStream;
- import com.work.util.zip.ZipEntry;
- /**
- * @project proxool-0.9.1 中的java.util.zip包和此类联合使用
- * @author wangmingjie
- *
- */
- public class ZipUtil {
- private static Log log = LogFactory.getLog(ZipUtil.class);
- /**
- * 解压缩文件夹。
- *
- * @param srcFilename
- * @param destFilename
- * @param overwrite
- * @throws IOException
- */
- public void unzipDir(String srcFilename,boolean overwrite) throws IOException {
- File srcFile = new File(srcFilename);
- // 首先判断源文件是否存在
- if (!srcFile.exists()) {
- throw new FileNotFoundException("Cannot find the source file: "
- + srcFile.getAbsolutePath());
- }
- // 判断源文件是否可读
- if (!srcFile.canRead()) {
- throw new IOException("Cannot read the source file: "
- + srcFile.getAbsolutePath());
- }
- FileInputStream fin = null;
- BufferedInputStream inputStream = null;
- ZipInputStream zipInputStream = null;
- try {
- fin = new FileInputStream(srcFile);
- inputStream = new BufferedInputStream(fin);
- zipInputStream = new ZipInputStream(inputStream, "gbk");//在这里设置编码格式,解决文件名和备注乱码问题
- ZipEntry zipEntry = null;
- String tempFileName = null;
- while ((zipEntry = zipInputStream.getNextEntry()) != null) {
- tempFileName = zipEntry.getName();
- if (zipEntry.isDirectory()) {
- // 创建文件夹
- FileUtil.createDirs(tempFileName, true);
- } else {
- tempFileName = tempFileName.replace("//", "/");
- //System.out.println("文件夹=" + tempFileName.substring(0,tempFileName.lastIndexOf("/")));
- FileUtil.createDirs(tempFileName.substring(0,tempFileName.lastIndexOf("/")), true);
- //System.out.println("tempFileName=" + tempFileName);
- unzipFile(zipInputStream, tempFileName); // 解压缩
- }
- zipInputStream.closeEntry();//关闭当前 ZIP 条目并定位流以读取下一个条目。
- //不写上面的一句,程序也能够正常运行。
- }
- } finally {
- if (zipInputStream != null) {
- try {
- zipInputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (fin != null) {
- try {
- fin.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- }
- }
- /**
- * 创建解压缩的文件
- *
- * @param srcFilename
- * @param zipInputStream
- * @throws IOException
- */
- private void unzipFile(InputStream zipInputStream, String destFileName)
- throws IOException {
- FileOutputStream fout = null;
- BufferedOutputStream outputStream = null;
- byte[] block = new byte[1024];
- try {
- if(log.isDebugEnabled()){
- log.debug("要生成的文件名称为:" + destFileName);
- }
- File destFile = new File(destFileName);
- // 如果要覆盖已经存在的目标文件,首先判断是否目标文件可写。
- if (destFile.exists()) {
- if (!destFile.canWrite()) {
- throw new IOException("Cannot write the destination file: "
- + destFile.getAbsolutePath());
- }
- } else {
- // 不存在就创建一个新的空文件。
- if (!destFile.createNewFile()) {
- throw new IOException("Cannot write the destination file: "
- + destFile.getAbsolutePath());
- }
- }
- fout = new FileOutputStream(destFile);
- outputStream = new BufferedOutputStream(fout);
- // 开始从zip文件中读取数据
- while (true) {
- int readLength = zipInputStream.read(block);
- if (readLength == -1)
- break;// end of file
- outputStream.write(block, 0, readLength);
- }
- outputStream.flush();
- } finally {
- if (outputStream != null) {
- try {
- outputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (fout != null) {
- try {
- fout.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- }
- }
- /**
- * 解压缩单个文件。程序测试的过度函数!
- *
- * @param srcFilename
- * @param destFilename
- * @param overwrite
- * @throws IOException
- */
- public void unzipFile(String srcFilename, String destFilename,
- boolean overwrite) throws IOException {
- File srcFile = new File(srcFilename);
- // 首先判断源文件是否存在
- if (!srcFile.exists()) {
- throw new FileNotFoundException("Cannot find the source file: "
- + srcFile.getAbsolutePath());
- }
- // 判断源文件是否可读
- if (!srcFile.canRead()) {
- throw new IOException("Cannot read the source file: "
- + srcFile.getAbsolutePath());
- }
- FileInputStream fin = null;
- BufferedInputStream inputStream = null;
- ZipInputStream zipInputStream = null;
- FileOutputStream fout = null;
- BufferedOutputStream outputStream = null;
- byte[] block = new byte[1024];
- try {
- fin = new FileInputStream(srcFile);
- inputStream = new BufferedInputStream(fin);
- zipInputStream = new ZipInputStream(inputStream, "gbk");
- ZipEntry zipEntry = zipInputStream.getNextEntry();
- if (destFilename == null || destFilename.trim().equals("")) {
- destFilename = zipEntry.getName();
- }
- System.out.println("解压缩生成的文件名称为:" + destFilename);
- File destFile = new File(destFilename);
- if (overwrite == false) {
- // 目标文件存在就不覆盖
- if (destFile.exists())
- return;
- } else {
- // 如果要覆盖已经存在的目标文件,首先判断是否目标文件可写。
- if (destFile.exists()) {
- if (!destFile.canWrite()) {
- throw new IOException(
- "Cannot write the destination file: "
- + destFile.getAbsolutePath());
- }
- } else {
- // 不存在就创建一个新的空文件。
- if (!destFile.createNewFile()) {
- throw new IOException(
- "Cannot write the destination file: "
- + destFile.getAbsolutePath());
- }
- }
- }
- fout = new FileOutputStream(destFile);
- outputStream = new BufferedOutputStream(fout);
- // 开始从zip文件中读取数据
- while (true) {
- int readLength = zipInputStream.read(block);
- if (readLength == -1)
- break;// end of file
- outputStream.write(block, 0, readLength);
- }
- outputStream.flush();
- } finally {
- if (zipInputStream != null) {
- try {
- zipInputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (fin != null) {
- try {
- fin.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (outputStream != null) {
- try {
- outputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (fout != null) {
- try {
- fout.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- }
- }
- /**
- * 压缩单个文件。
- *
- * @param srcFilename
- * @param destFilename
- * @param overwrite
- * @throws IOException
- */
- /**
- * @param srcFilename
- * @param destDir 目标文件保存在哪个文件夹下面
- * @param destFilename
- * @param overwrite
- * @throws IOException
- */
- public void zipFile(String srcFilename, String destDir,String destFilename,
- boolean overwrite) throws IOException {
- File srcFile = new File(srcFilename);
- // 首先判断源文件是否存在
- if (!srcFile.exists()) {
- throw new FileNotFoundException("Cannot find the source file: "
- + srcFile.getAbsolutePath());
- }
- // 判断源文件是否可读
- if (!srcFile.canRead()) {
- throw new IOException("Cannot read the source file: "
- + srcFile.getAbsolutePath());
- }
- if (destFilename == null || destFilename.trim().equals("")) {
- destFilename = srcFilename + ".zip";
- } else {
- destFilename += ".zip";
- }
- destDir = (destDir.endsWith("/") || destDir.endsWith("//"))?destDir.substring(0,destDir.length()-1):destDir;
- File destFile = new File(destDir+"/"+destFilename);
- if (overwrite == false) {
- // 目标文件存在就不覆盖
- if (destFile.exists())
- return;
- } else {
- // 如果要覆盖已经存在的目标文件,首先判断是否目标文件可写。
- if (destFile.exists()) {
- if (!destFile.canWrite()) {
- throw new IOException("Cannot write the destination file: "
- + destFile.getAbsolutePath());
- }
- } else {
- // 不存在就创建一个新的空文件。
- if (!destFile.createNewFile()) {
- throw new IOException("Cannot write the destination file: "
- + destFile.getAbsolutePath());
- }
- }
- }
- FileInputStream fin = null;
- BufferedInputStream inputStream = null;
- FileOutputStream fout = new FileOutputStream(destFile);
- BufferedOutputStream outputStream = null;
- ZipOutputStream zipOutputStream = null;
- byte[] block = new byte[1024];
- try {
- fin = new FileInputStream(srcFile);
- inputStream = new BufferedInputStream(fin);
- outputStream = new BufferedOutputStream(fout);
- zipOutputStream = new ZipOutputStream(outputStream, "gbk");
- zipOutputStream.setComment("通过java程序压缩的,压缩时间为:"+DateUtil.getCurrentDateTime());
- ZipEntry zipEntry = new ZipEntry(srcFile.getName());
- zipEntry.setComment(" zipEntry通过java程序压缩的");
- zipOutputStream.putNextEntry(zipEntry);
- while (true) {
- int readLength = inputStream.read(block);
- if (readLength == -1)
- break;// end of file
- zipOutputStream.write(block, 0, readLength);
- }
- zipOutputStream.flush();
- zipOutputStream.finish();
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (fin != null) {
- try {
- fin.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (zipOutputStream != null) {
- try {
- zipOutputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (outputStream != null) {
- try {
- outputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (fout != null) {
- try {
- fout.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- }
- }
- /**
- *
- * @param srcFilename
- * 源文件
- * @param destFilename
- * 目标文件名称,如果为空,那么就使用源文件的名称+.zip作为文件名
- * @param overwrite
- * 如果目标文件存在是否覆盖源文件,默认是不覆盖。
- * @throws IOException
- */
- public void zipDir(String srcFilename, String destFilename,
- boolean overwrite) throws IOException {
- File srcFile = new File(srcFilename);
- // 首先判断源文件是否存在
- if (!srcFile.exists()) {
- throw new FileNotFoundException("Cannot find the source file: "
- + srcFile.getAbsolutePath());
- }
- // 判断源文件是否可读
- if (!srcFile.canRead()) {
- throw new IOException("Cannot read the source file: "
- + srcFile.getAbsolutePath());
- }
- if (destFilename == null || destFilename.trim().equals("")) {
- destFilename = srcFilename + ".zip";
- } else {
- destFilename += ".zip";
- }
- File destFile = new File(destFilename);
- if (overwrite == false) {
- // 目标文件存在就不覆盖
- if (destFile.exists())
- return;
- } else {
- // 如果要覆盖已经存在的目标文件,首先判断是否目标文件可写。
- if (destFile.exists()) {
- if (!destFile.canWrite()) {
- throw new IOException("Cannot write the destination file: "
- + destFile.getAbsolutePath());
- }
- } else {
- // 不存在就创建一个新的空文件。
- if (!destFile.createNewFile()) {
- throw new IOException("Cannot write the destination file: "
- + destFile.getAbsolutePath());
- }
- }
- }
- BufferedOutputStream outputStream = null;
- ZipOutputStream zipOutputStream = null;
- FileOutputStream fout = new FileOutputStream(destFile);
- outputStream = new BufferedOutputStream(fout);
- zipOutputStream = new ZipOutputStream(outputStream, "gbk");
- zipOutputStream.setComment("通过java程序压缩的");
- try {
- zipDir(srcFile, zipOutputStream);// 压缩文件
- zipOutputStream.flush();
- zipOutputStream.finish();
- } finally {
- if (zipOutputStream != null) {
- try {
- zipOutputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (outputStream != null) {
- try {
- outputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (fout != null) {
- try {
- fout.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- }
- }
- /**
- * 压缩文件夹
- *
- * @param srcFile
- * @param zipOutputStream
- * @throws IOException
- */
- private void zipDir(File srcFile, ZipOutputStream zipOutputStream)
- throws IOException {
- if (srcFile.isFile()) {
- if (log.isDebugEnabled()) {
- log.debug(srcFile.getAbsolutePath());
- }
- System.out.println("要压缩的文件"+srcFile.getAbsolutePath());
- FileInputStream fin = null;
- BufferedInputStream inputStream = null;
- byte[] block = new byte[1024];
- try {
- fin = new FileInputStream(srcFile);
- inputStream = new BufferedInputStream(fin);
- ZipEntry zipEntry = new ZipEntry(srcFile.getAbsolutePath());// 获取文件的绝对路径
- zipOutputStream.putNextEntry(zipEntry);
- while (true) {
- int readLength = inputStream.read(block);
- if (readLength == -1)
- break;// end of file
- zipOutputStream.write(block, 0, readLength);
- }
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- if (fin != null) {
- try {
- fin.close();
- } catch (IOException ex) {
- // just ignore
- }
- }
- }
- }
- if (srcFile.isDirectory()) { // 文件夹,进行递归
- File[] srcFiles = srcFile.listFiles();
- for (File temp : srcFiles) {
- zipDir(temp, zipOutputStream);
- }
- }
- }
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- // ZipUtil z = new ZipUtil();
- // // z.zipDir("d:/logs", "", true);
- // // System.out.println("压缩结束");
- // z.unzipDir("d:/logs.zip", true);
- // System.out.println("解压缩结束");
- String sysTemp = System.getProperty("java.io.tmpdir");//获取到系统临时目录
- //C:/DOCUME~1/WANGMI~1/LOCALS~1/Temp/
- sysTemp = sysTemp.replace("//", "/");
- ZipUtil z = new ZipUtil();
- z.zipFile("d:/logs/work.log",sysTemp,System.currentTimeMillis()+"", true);
- System.out.println("结束");
- }
- }