⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cnzipoutputstream.java

📁 Java实用程序设计100例程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * @(#)CNZipOutputStream.java	1.27 03/02/07
 *
 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.util.zip;

import java.io.OutputStream;
import java.io.IOException;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;

/**
 * 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.27, 02/07/03
 */
public
class CNZipOutputStream 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;
    private long locoff = 0;
    private String comment;
    private int method = DEFLATED;
    private boolean finished;
    private String encoding="UTF-8"; 

    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;

    /**
     * Creates a new ZIP output stream.
     * @param out the actual output stream
     */
    public CNZipOutputStream(OutputStream out) {
	super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
        usesDefaultDeflater = true;
    }
    
   public CNZipOutputStream(OutputStream out,String encoding) { 
     super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true)); 
     usesDefaultDeflater = true; 
     this.encoding=encoding; 
  } 


    /**
     * 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.getTotalIn()) {
			throw new ZipException(
			    "invalid entry size (expected " + e.size +
			    " but got " + def.getTotalIn() + " bytes)");
		    }
		    if (e.csize != def.getTotalOut()) {
			throw new ZipException(
			    "invalid entry compressed size (expected " +
			    e.csize + " but got " + def.getTotalOut() +
			    " 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.getTotalIn();
		    e.csize = def.getTotalOut();
		    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) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -