czipoutputstream.java
来自「对eclipse gef进行封装,可以生成图形化编辑器」· Java 代码 · 共 536 行 · 第 1/2 页
JAVA
536 行
/*******************************************************************************
* $Header: /cvsroot/EOS6/work_dir/niegy/com.primeton.studio.gef.ui/src/com/primeton/studio/gef/ui/zip/CZipOutputStream.java,v 1.1 2007/01/23 06:35:15 niegy Exp $
* $Revision: 1.1 $
* $Date: 2007/01/23 06:35:15 $
*
*==============================================================================
*
* Copyright (c) 2001-2006 Primeton Technologies, Ltd.
* All rights reserved.
*
* Created on 2007-1-22
*******************************************************************************/
package com.primeton.studio.gef.ui.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.DeflaterOutputStream;
import java.util.zip.ZipException;
/**
* TODO 此处填写 class 信息
*
* @author niegy (mailto:niegy@primeton.com)
*/
/*
* 修改历史
* $Log: CZipOutputStream.java,v $
* Revision 1.1 2007/01/23 06:35:15 niegy
* 实现压缩功能,支持中文
*
*/
class CZipOutputStream extends DeflaterOutputStream implements CZipConstants {
private String encoding="UTF-8";
private CZipEntry 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 = CZipEntry.STORED;
/**
* Compression method for compressed (DEFLATED) entries.
*/
public static final int DEFLATED = CZipEntry.DEFLATED;
/**
* Creates a new ZIP output stream.
* @param out the actual output stream
*/
public CZipOutputStream(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(CZipEntry 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();
CZipEntry 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) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?