Methods Summary |
---|
public void | close()Closes the ZIP output stream as well as the stream being filtered.
if (!closed) {
super.close();
closed = true;
}
|
public void | closeEntry()Closes the current ZIP entry and positions the stream for writing
the next entry.
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;
}
|
private void | ensureOpen()Check to make sure that this stream has not been closed
if (closed) {
throw new IOException("Stream closed");
}
|
public void | finish()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.
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;
|
private static byte[] | getUTF8Bytes(java.lang.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;
|
static int | getUTF8Length(java.lang.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;
|
public void | putNextEntry(java.util.zip.ZipEntry e)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.
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;
|
public void | setComment(java.lang.String comment)Sets the ZIP file comment.
if (comment != null && comment.length() > 0xffff/3
&& getUTF8Length(comment) > 0xffff) {
throw new IllegalArgumentException("ZIP file comment too long.");
}
this.comment = comment;
|
public void | setLevel(int level)Sets the compression level for subsequent entries which are DEFLATED.
The default setting is DEFAULT_COMPRESSION.
def.setLevel(level);
|
public void | setMethod(int method)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.
if (method != DEFLATED && method != STORED) {
throw new IllegalArgumentException("invalid compression method");
}
this.method = method;
|
public synchronized void | write(byte[] b, int off, int len)Writes an array of bytes to the current ZIP entry data. This method
will block until all the bytes are written.
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);
|
private void | writeBytes(byte[] b, int off, int len)
super.out.write(b, off, len);
written += len;
|
private void | writeCEN(java.util.zip.ZipEntry e)
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);
writeShort(nameBytes.length);
writeShort(e.extra != null ? e.extra.length : 0);
byte[] commentBytes;
if (e.comment != null) {
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);
}
|
private void | writeEND(long off, long len)
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);
writeShort(b.length);
writeBytes(b, 0, b.length);
} else {
writeShort(0);
}
|
private void | writeEXT(java.util.zip.ZipEntry e)
writeInt(EXTSIG); // EXT header signature
writeInt(e.crc); // crc-32
writeInt(e.csize); // compressed size
writeInt(e.size); // uncompressed size
|
private void | writeInt(long v)
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;
|
private void | writeLOC(java.util.zip.ZipEntry e)
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);
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;
|
private void | writeShort(int v)
OutputStream out = this.out;
out.write((v >>> 0) & 0xff);
out.write((v >>> 8) & 0xff);
written += 2;
|