org.apache.tools.zip
Class ZipOutputStream

java.lang.Object
  extended by java.io.OutputStream
      extended by java.io.FilterOutputStream
          extended by org.apache.tools.zip.ZipOutputStream
All Implemented Interfaces:
java.io.Closeable, java.io.Flushable

public class ZipOutputStream
extends java.io.FilterOutputStream

Reimplementation of java.util.zip.ZipOutputStream that does handle the extended functionality of this package, especially internal/external file attributes and extra fields with different layouts for local file data and central directory entries.

This class will try to use RandomAccessFile when you know that the output is going to go to a file.

If RandomAccessFile cannot be used, this implementation will use a Data Descriptor to store size and CRC information for DEFLATED entries, this means, you don't need to calculate them yourself. Unfortunately this is not possible for the STORED method, here setting the CRC and uncompressed size information is required before putNextEntry can be called.

As of Apache Ant 1.9.0 it transparently supports Zip64 extensions and thus individual entries and archives larger than 4 GB or with more than 65536 entries in most cases but explicit control is provided via setUseZip64(org.apache.tools.zip.Zip64Mode). If the stream can not user RandomAccessFile and you try to write a ZipEntry of unknown size then Zip64 extensions will be disabled by default.


Nested Class Summary
static class ZipOutputStream.UnicodeExtraFieldPolicy
          enum that represents the possible policies for creating Unicode extra fields.
 
Field Summary
protected  byte[] buf
          This buffer serves as a Deflater.
protected static byte[] CFH_SIG
          central file header signature
protected static byte[] DD_SIG
          data descriptor signature
protected  java.util.zip.Deflater def
          This Deflater object is used for output.
static int DEFAULT_COMPRESSION
          Default compression level for deflated entries.
static int DEFLATED
          Compression method for deflated entries.
static int EFS_FLAG
          Deprecated. use GeneralPurposeBit.UFT8_NAMES_FLAG instead
protected static byte[] EOCD_SIG
          end of central dir signature
protected static byte[] LFH_SIG
          local file header signature
static int STORED
          Compression method for stored entries.
 
Fields inherited from class java.io.FilterOutputStream
out
 
Constructor Summary
ZipOutputStream(java.io.File file)
          Creates a new ZIP OutputStream writing to a File.
ZipOutputStream(java.io.OutputStream out)
          Creates a new ZIP OutputStream filtering the underlying stream.
 
Method Summary
protected static long adjustToLong(int i)
          Deprecated. use ZipUtil#adjustToLong
 boolean canWriteEntryData(ZipEntry ae)
          Whether this stream is able to write the given entry.
 void close()
          Closes this output stream and releases any system resources associated with the stream.
 void closeEntry()
          Writes all necessary data for this entry.
protected  void deflate()
          Writes next block of compressed data to the output stream.
 void finish()
          
 void flush()
          Flushes this output stream and forces any buffered output bytes to be written out to the stream.
protected  byte[] getBytes(java.lang.String name)
          Retrieve the bytes for the given String in the encoding set for this Stream.
 java.lang.String getEncoding()
          The encoding to use for filenames and the file comment.
 boolean isSeekable()
          This method indicates whether this archive is writing to a seekable stream (i.e., to a random access file).
 void putNextEntry(ZipEntry archiveEntry)
          
 void setComment(java.lang.String comment)
          Set the file comment.
 void setCreateUnicodeExtraFields(ZipOutputStream.UnicodeExtraFieldPolicy b)
          Whether to create Unicode Extra Fields.
 void setEncoding(java.lang.String encoding)
          The encoding to use for filenames and the file comment.
 void setFallbackToUTF8(boolean b)
          Whether to fall back to UTF and the language encoding flag if the file name cannot be encoded using the specified encoding.
 void setLevel(int level)
          Sets the compression level for subsequent entries.
 void setMethod(int method)
          Sets the default compression method for subsequent entries.
 void setUseLanguageEncodingFlag(boolean b)
          Whether to set the language encoding flag if the file name encoding is UTF-8.
 void setUseZip64(Zip64Mode mode)
          Whether Zip64 extensions will be used.
protected static ZipLong toDosTime(java.util.Date time)
          Deprecated. use ZipUtil#toDosTime
protected static byte[] toDosTime(long t)
          Deprecated. use ZipUtil#toDosTime
 void write(byte[] b, int offset, int length)
          Writes bytes to ZIP entry.
protected  void writeCentralDirectoryEnd()
          Writes the "End of central dir record".
protected  void writeCentralFileHeader(ZipEntry ze)
          Writes the central file header entry.
protected  void writeDataDescriptor(ZipEntry ze)
          Writes the data descriptor entry.
protected  void writeLocalFileHeader(ZipEntry ze)
          Writes the local file header entry
protected  void writeOut(byte[] data)
          Write bytes to output or random access file.
protected  void writeOut(byte[] data, int offset, int length)
          Write bytes to output or random access file.
protected  void writeZip64CentralDirectory()
          Writes the "ZIP64 End of central dir record" and "ZIP64 End of central dir locator".
 
Methods inherited from class java.io.FilterOutputStream
write, write
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFLATED

public static final int DEFLATED
Compression method for deflated entries.

Since:
1.1
See Also:
Constant Field Values

DEFAULT_COMPRESSION

public static final int DEFAULT_COMPRESSION
Default compression level for deflated entries.

Since:
Ant 1.7
See Also:
Constant Field Values

STORED

public static final int STORED
Compression method for stored entries.

Since:
1.1
See Also:
Constant Field Values

EFS_FLAG

@Deprecated
public static final int EFS_FLAG
Deprecated. use GeneralPurposeBit.UFT8_NAMES_FLAG instead
General purpose flag, which indicates that filenames are written in utf-8.

See Also:
Constant Field Values

def

protected final java.util.zip.Deflater def
This Deflater object is used for output.


buf

protected byte[] buf
This buffer serves as a Deflater.

This attribute is only protected to provide a level of API backwards compatibility. This class used to extend DeflaterOutputStream up to Revision 1.13.

Since:
1.14

LFH_SIG

protected static final byte[] LFH_SIG
local file header signature

Since:
1.1

DD_SIG

protected static final byte[] DD_SIG
data descriptor signature

Since:
1.1

CFH_SIG

protected static final byte[] CFH_SIG
central file header signature

Since:
1.1

EOCD_SIG

protected static final byte[] EOCD_SIG
end of central dir signature

Since:
1.1
Constructor Detail

ZipOutputStream

public ZipOutputStream(java.io.OutputStream out)
Creates a new ZIP OutputStream filtering the underlying stream.

Parameters:
out - the outputstream to zip
Since:
1.1

ZipOutputStream

public ZipOutputStream(java.io.File file)
                throws java.io.IOException
Creates a new ZIP OutputStream writing to a File. Will use random access if possible.

Parameters:
file - the file to zip to
Throws:
java.io.IOException - on error
Since:
1.14
Method Detail

isSeekable

public boolean isSeekable()
This method indicates whether this archive is writing to a seekable stream (i.e., to a random access file).

For seekable streams, you don't need to calculate the CRC or uncompressed size for STORED entries before invoking putNextEntry(org.apache.tools.zip.ZipEntry).

Returns:
true if seekable
Since:
1.17

setEncoding

public void setEncoding(java.lang.String encoding)
The encoding to use for filenames and the file comment.

For a list of possible values see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html. Defaults to the platform's default character encoding.

Parameters:
encoding - the encoding value
Since:
1.3

getEncoding

public java.lang.String getEncoding()
The encoding to use for filenames and the file comment.

Returns:
null if using the platform's default character encoding.
Since:
1.3

setUseLanguageEncodingFlag

public void setUseLanguageEncodingFlag(boolean b)
Whether to set the language encoding flag if the file name encoding is UTF-8.

Defaults to true.


setCreateUnicodeExtraFields

public void setCreateUnicodeExtraFields(ZipOutputStream.UnicodeExtraFieldPolicy b)
Whether to create Unicode Extra Fields.

Defaults to NEVER.


setFallbackToUTF8

public void setFallbackToUTF8(boolean b)
Whether to fall back to UTF and the language encoding flag if the file name cannot be encoded using the specified encoding.

Defaults to false.


setUseZip64

public void setUseZip64(Zip64Mode mode)
Whether Zip64 extensions will be used.

When setting the mode to Never, putNextEntry(org.apache.tools.zip.ZipEntry), closeEntry(), finish() or close() may throw a Zip64RequiredException if the entry's size or the total size of the archive exceeds 4GB or there are more than 65536 entries inside the archive. Any archive created in this mode will be readable by implementations that don't support Zip64.

When setting the mode to Always, Zip64 extensions will be used for all entries. Any archive created in this mode may be unreadable by implementations that don't support Zip64 even if all its contents would be.

When setting the mode to AsNeeded, Zip64 extensions will transparently be used for those entries that require them. This mode can only be used if the uncompressed size of the ZipEntry is known when calling putNextEntry(org.apache.tools.zip.ZipEntry) or the archive is written to a seekable output (i.e. you have used the File-arg constructor) - this mode is not valid when the output stream is not seekable and the uncompressed size is unknown when putNextEntry(org.apache.tools.zip.ZipEntry) is called.

If no entry inside the resulting archive requires Zip64 extensions then Never will create the smallest archive. AsNeeded will create a slightly bigger archive if the uncompressed size of any entry has initially been unknown and create an archive identical to Never otherwise. Always will create an archive that is at least 24 bytes per entry bigger than the one Never would create.

Defaults to AsNeeded unless putNextEntry(org.apache.tools.zip.ZipEntry) is called with an entry of unknown size and data is written to a non-seekable stream - in this case the default is Never.

Since:
1.3

finish

public void finish()
            throws java.io.IOException

Throws:
Zip64RequiredException - if the archive's size exceeds 4 GByte or there are more than 65535 entries inside the archive and setUseZip64(org.apache.tools.zip.Zip64Mode) is Zip64Mode.Never.
java.io.IOException

closeEntry

public void closeEntry()
                throws java.io.IOException
Writes all necessary data for this entry.

Throws:
java.io.IOException - on error
Zip64RequiredException - if the entry's uncompressed or compressed size exceeds 4 GByte and setUseZip64(org.apache.tools.zip.Zip64Mode) is Zip64Mode.Never.
Since:
1.1

putNextEntry

public void putNextEntry(ZipEntry archiveEntry)
                  throws java.io.IOException

Throws:
Zip64RequiredException - if the entry's uncompressed or compressed size is known to exceed 4 GByte and setUseZip64(org.apache.tools.zip.Zip64Mode) is Zip64Mode.Never.
java.io.IOException

setComment

public void setComment(java.lang.String comment)
Set the file comment.

Parameters:
comment - the comment

setLevel

public void setLevel(int level)
Sets the compression level for subsequent entries.

Default is Deflater.DEFAULT_COMPRESSION.

Parameters:
level - the compression level.
Throws:
java.lang.IllegalArgumentException - if an invalid compression level is specified.
Since:
1.1

setMethod

public void setMethod(int method)
Sets the default compression method for subsequent entries.

Default is DEFLATED.

Parameters:
method - an int from java.util.zip.ZipEntry
Since:
1.1

canWriteEntryData

public boolean canWriteEntryData(ZipEntry ae)
Whether this stream is able to write the given entry.

May return false if it is set up to use encryption or a compression method that hasn't been implemented yet.


write

public void write(byte[] b,
                  int offset,
                  int length)
           throws java.io.IOException
Writes bytes to ZIP entry.

Overrides:
write in class java.io.FilterOutputStream
Parameters:
b - the byte array to write
offset - the start position to write from
length - the number of bytes to write
Throws:
java.io.IOException - on error

close

public void close()
           throws java.io.IOException
Closes this output stream and releases any system resources associated with the stream.

Specified by:
close in interface java.io.Closeable
Overrides:
close in class java.io.FilterOutputStream
Throws:
java.io.IOException - if an I/O error occurs.
Zip64RequiredException - if the archive's size exceeds 4 GByte or there are more than 65535 entries inside the archive and setUseZip64(org.apache.tools.zip.Zip64Mode) is Zip64Mode.Never.

flush

public void flush()
           throws java.io.IOException
Flushes this output stream and forces any buffered output bytes to be written out to the stream.

Specified by:
flush in interface java.io.Flushable
Overrides:
flush in class java.io.FilterOutputStream
Throws:
java.io.IOException - if an I/O error occurs.

deflate

protected final void deflate()
                      throws java.io.IOException
Writes next block of compressed data to the output stream.

Throws:
java.io.IOException - on error
Since:
1.14

writeLocalFileHeader

protected void writeLocalFileHeader(ZipEntry ze)
                             throws java.io.IOException
Writes the local file header entry

Parameters:
ze - the entry to write
Throws:
java.io.IOException - on error
Since:
1.1

writeDataDescriptor

protected void writeDataDescriptor(ZipEntry ze)
                            throws java.io.IOException
Writes the data descriptor entry.

Parameters:
ze - the entry to write
Throws:
java.io.IOException - on error
Since:
1.1

writeCentralFileHeader

protected void writeCentralFileHeader(ZipEntry ze)
                               throws java.io.IOException
Writes the central file header entry.

Parameters:
ze - the entry to write
Throws:
java.io.IOException - on error
Zip64RequiredException - if the archive's size exceeds 4 GByte and #setUseZip64 is Zip64Mode.Never.

writeCentralDirectoryEnd

protected void writeCentralDirectoryEnd()
                                 throws java.io.IOException
Writes the "End of central dir record".

Throws:
java.io.IOException - on error
Zip64RequiredException - if the archive's size exceeds 4 GByte or there are more than 65535 entries inside the archive and #setUseZip64 is Zip64Mode.Never.

toDosTime

protected static ZipLong toDosTime(java.util.Date time)
Deprecated. use ZipUtil#toDosTime

Convert a Date object to a DOS date/time field.

Parameters:
time - the Date to convert
Returns:
the date as a ZipLong
Since:
1.1

toDosTime

protected static byte[] toDosTime(long t)
Deprecated. use ZipUtil#toDosTime

Convert a Date object to a DOS date/time field.

Stolen from InfoZip's fileio.c

Parameters:
t - number of milliseconds since the epoch
Returns:
the date as a byte array
Since:
1.26

getBytes

protected byte[] getBytes(java.lang.String name)
                   throws java.util.zip.ZipException
Retrieve the bytes for the given String in the encoding set for this Stream.

Parameters:
name - the string to get bytes from
Returns:
the bytes as a byte array
Throws:
java.util.zip.ZipException - on error
Since:
1.3

writeZip64CentralDirectory

protected void writeZip64CentralDirectory()
                                   throws java.io.IOException
Writes the "ZIP64 End of central dir record" and "ZIP64 End of central dir locator".

Throws:
java.io.IOException - on error

writeOut

protected final void writeOut(byte[] data)
                       throws java.io.IOException
Write bytes to output or random access file.

Parameters:
data - the byte array to write
Throws:
java.io.IOException - on error
Since:
1.14

writeOut

protected final void writeOut(byte[] data,
                              int offset,
                              int length)
                       throws java.io.IOException
Write bytes to output or random access file.

Parameters:
data - the byte array to write
offset - the start position to write from
length - the number of bytes to write
Throws:
java.io.IOException - on error
Since:
1.14

adjustToLong

protected static long adjustToLong(int i)
Deprecated. use ZipUtil#adjustToLong

Assumes a negative integer really is a positive integer that has wrapped around and re-creates the original value.

Parameters:
i - the value to treat as unsigned int.
Returns:
the unsigned int as a long.
Since:
1.34