com.mucommander.file.impl.zip.provider
Class ZipOutputStream

java.lang.Object
  extended by java.io.OutputStream
      extended by com.mucommander.file.impl.zip.provider.ZipOutputStream
All Implemented Interfaces:
ZipConstants, java.io.Closeable, java.io.Flushable

public class ZipOutputStream
extends java.io.OutputStream
implements ZipConstants

Reimplementation of java.util.zip.ZipOutputStream that handles 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 is based off the org.apache.tools.zip package of the Apache Ant project. The Ant code has been modified under the terms of the Apache License which you can find in the bundled muCommander license file. It was forked at version 1.7.0 of Ant.

Author:
Apache Ant, Maxence Bernard

Field Summary
protected  java.util.zip.Deflater deflater
          Deflater instance that is used to compress DEFLATED entries
protected  byte[] deflaterBuf
          Buffer used by Deflater to deflate data
protected  java.io.OutputStream out
          The underlying stream this ZipOutputStream writes zip-compressed data to.
 
Fields inherited from interface com.mucommander.file.impl.zip.provider.ZipConstants
CFH_SIG, DD_SIG, DEFAULT_DEFLATER_BUFFER_SIZE, DEFAULT_DEFLATER_COMPRESSION, DEFLATED, EOCD_SIG, LFH_SIG, MAX_ZIP32_SIZE, STORED, UTF_8, WRITE_BUFFER_SIZE
 
Constructor Summary
ZipOutputStream(java.io.OutputStream out)
          Creates a new ZipOutputStream that writes Zip-compressed data to the given OutputStream.
 
Method Summary
protected static long adjustToLong(int i)
          Returns a long that is the unsigned intepretation of the given (signed) int.
 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 static void finalizeEntryData(ZipEntry entry, ZipEntryOutputStream zeos, java.io.OutputStream out, boolean useDataDescriptor, ZipBuffer zipBuffer)
          Writes the size and CRC information of an entry.
 void finish()
          Finishs writing the contents and closes this as well as the underlying stream.
 void flush()
          Flushes this output stream and forces any buffered output bytes to be written out to the stream.
protected static byte[] getBytes(java.lang.String name, java.lang.String encoding)
          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 RandomAccessOutputStream.
 void putNextEntry(ZipEntry ze)
          Start writing the given entry.
 void setComment(java.lang.String comment)
          Sets the file comment.
 void setEncoding(java.lang.String encoding)
          The encoding to use for filenames and the file comment.
 void setLevel(int level)
          Sets the compression level for subsequent entries.
 void setMethod(int method)
          Sets the default compression method for subsequent entries.
 void write(byte[] b)
          Writes the given bytes to the current Zip entry opened with putNextEntry(ZipEntry), using the entry's compression method.
 void write(byte[] b, int offset, int length)
          Writes the given bytes to the current Zip entry opened with putNextEntry(ZipEntry), using the entry's compression method.
 void write(int b)
          Writes a single byte to the current Zip entry opened with putNextEntry(ZipEntry), using the entry's compression method.
protected static void writeCentralDirectoryEnd(java.io.OutputStream out, int nbEntries, long cdLength, long cdOffset, java.lang.String comment, java.lang.String encoding, ZipBuffer zipBuffer)
          Writes the end of the central directory record.
protected static long writeCentralFileHeader(ZipEntry ze, java.io.OutputStream out, java.lang.String encoding, long localFileHeaderOffset, boolean useDataDescriptor, ZipBuffer zipBuffer)
          Writes the central file header for the given entry.
protected static long writeDataDescriptor(ZipEntry ze, java.io.OutputStream out, ZipBuffer zipBuffer)
          Writes the data descriptor, using the CRC, compressed and uncompressed size attributes contained in the given ZipEntry.
protected static long writeLocalFileHeader(ZipEntry ze, java.io.OutputStream out, java.lang.String encoding, boolean useDataDescriptor, ZipBuffer zipBuffer)
          Writes the local file header entry.
protected static long writeVersionAndGPBF(java.io.OutputStream out, java.lang.String encoding, boolean useDataDescriptor)
          Writes the 'version needed to extract' (2 bytes) and 'general purpose bit flag' (2 bytes) fields.
protected static long writeVersionMadeBy(ZipEntry ze, java.io.OutputStream out, ZipBuffer zipBuffer)
          Writes central file header's 'Version made by' field, using the platform contained in the given ZipEntry.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

deflater

protected java.util.zip.Deflater deflater
Deflater instance that is used to compress DEFLATED entries


deflaterBuf

protected byte[] deflaterBuf
Buffer used by Deflater to deflate data


out

protected java.io.OutputStream out
The underlying stream this ZipOutputStream writes zip-compressed data to.

Constructor Detail

ZipOutputStream

public ZipOutputStream(java.io.OutputStream out)
Creates a new ZipOutputStream that writes Zip-compressed data to the given OutputStream. If a RandomAccessOutputStream is supplied, the Zip entries will be written without data descriptor, which will yield a slightly smaller file.

Parameters:
out - the underlying OutputStream stream where compressed data is written to
Method Detail

isSeekable

public boolean isSeekable()
This method indicates whether this archive is writing to a RandomAccessOutputStream.

Returns:
true if seekable

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

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.

finish

public void finish()
            throws java.io.IOException
Finishs writing the contents and closes this as well as the underlying stream.

Throws:
java.io.IOException - on error

closeEntry

public void closeEntry()
                throws java.io.IOException
Writes all necessary data for this entry. This method must be called after an entry opened by putNextEntry(ZipEntry) has finished being written.

Throws:
java.io.IOException - on error

finalizeEntryData

protected static void finalizeEntryData(ZipEntry entry,
                                        ZipEntryOutputStream zeos,
                                        java.io.OutputStream out,
                                        boolean useDataDescriptor,
                                        ZipBuffer zipBuffer)
                                 throws java.io.IOException
Writes the size and CRC information of an entry. This method is to be called right after a file entry's data has been written.

The size and CRC information is written to the given OutputStream, either as a data descriptor or in the entry's local file header, and is set in the given ZipEntry instance.

Parameters:
entry - the entry
zeos - the Zip entry's output stream
out - the
useDataDescriptor - if true, a data descriptor will be written to out. If false, size and CRC information will be written in the local file header (requires out to be a RandomAccessOutputStream).
zipBuffer - a ZipBuffer instance used to convert integer values to Zip variants
Throws:
java.io.IOException - if an I/O error occurred

putNextEntry

public void putNextEntry(ZipEntry ze)
                  throws java.io.IOException
Start writing the given entry. The entry is written by calling the write() of this class. When the entry has finished being written, closeEntry() must be called.

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

setComment

public void setComment(java.lang.String comment)
Sets 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.

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

writeLocalFileHeader

protected static long writeLocalFileHeader(ZipEntry ze,
                                           java.io.OutputStream out,
                                           java.lang.String encoding,
                                           boolean useDataDescriptor,
                                           ZipBuffer zipBuffer)
                                    throws java.io.IOException
Writes the local file header entry.

Parameters:
ze - the entry to write
out - the OutputStream to write the header to
encoding - the encoding to use for writing the entry's filename. If UTF-8 is used, the general purpose bit flag will be set accordingly.
useDataDescriptor - indicates whether a data descriptor will follow the file entry's data. The general purpose bit flag will be set accordingly.
zipBuffer - a ZipBuffer instance used to convert integer values to Zip variants
Returns:
the size (number of bytes) of the written local file header
Throws:
java.io.IOException - if an I/O error occurred

writeDataDescriptor

protected static long writeDataDescriptor(ZipEntry ze,
                                          java.io.OutputStream out,
                                          ZipBuffer zipBuffer)
                                   throws java.io.IOException
Writes the data descriptor, using the CRC, compressed and uncompressed size attributes contained in the given ZipEntry. The length of the field is returned, it is always 16 bytes.

Parameters:
ze - the entry for which to write the data descriptor
out - the OutputStream where to write the data descriptor to
zipBuffer - a ZipBuffer instance used to convert integer values to Zip variants
Returns:
the number of bytes that were written, i.e. the size of the data descriptor (16 bytes)
Throws:
java.io.IOException - if an I/O error occurred

writeVersionMadeBy

protected static long writeVersionMadeBy(ZipEntry ze,
                                         java.io.OutputStream out,
                                         ZipBuffer zipBuffer)
                                  throws java.io.IOException
Writes central file header's 'Version made by' field, using the platform contained in the given ZipEntry. The length of the field is returned, it is always 2 bytes.

Parameters:
ze - the entry for which to write the 'Version made by' field
out - the OutputStream where to write the field
zipBuffer - a ZipBuffer instance used to convert integer values to Zip variants
Returns:
the number of bytes that were written, i.e. the size of the 'Version made by' field (2 bytes)
Throws:
java.io.IOException - if an I/O error occurred

writeCentralFileHeader

protected static long writeCentralFileHeader(ZipEntry ze,
                                             java.io.OutputStream out,
                                             java.lang.String encoding,
                                             long localFileHeaderOffset,
                                             boolean useDataDescriptor,
                                             ZipBuffer zipBuffer)
                                      throws java.io.IOException
Writes the central file header for the given entry.

Parameters:
ze - the entry for which to write the central file header
out - the OutputStream to write the central file header to
encoding - the encoding to use for writing the filename and optional comment
localFileHeaderOffset - the offset to the local file header start
useDataDescriptor - true if a data descriptor is used for the entry
zipBuffer - a ZipBuffer instance used to convert integer values to Zip variants
Returns:
the number of bytes that were written, i.e. the size of the central file header
Throws:
java.io.IOException - if an I/O error occurred

writeVersionAndGPBF

protected static long writeVersionAndGPBF(java.io.OutputStream out,
                                          java.lang.String encoding,
                                          boolean useDataDescriptor)
                                   throws java.io.IOException
Writes the 'version needed to extract' (2 bytes) and 'general purpose bit flag' (2 bytes) fields.

Parameters:
out - the OutputStream to write the fields to
encoding - the encoding used for writing the filename and optional comment
useDataDescriptor - true if a data descriptor is used for the entry
Returns:
the number of bytes that were written, i.e. 4
Throws:
java.io.IOException - if an I/O error occurred

writeCentralDirectoryEnd

protected static void writeCentralDirectoryEnd(java.io.OutputStream out,
                                               int nbEntries,
                                               long cdLength,
                                               long cdOffset,
                                               java.lang.String comment,
                                               java.lang.String encoding,
                                               ZipBuffer zipBuffer)
                                        throws java.io.IOException
Writes the end of the central directory record.

Parameters:
out - the OutputStream to write the end of the central directory record to
nbEntries - number of entries the Zip file contains
cdLength - length (in bytes) of the central directory record
cdOffset - offset from the beginning of the Zip file to the start of the central directory record
comment - the optional Zip file comment
encoding - the encoding to use for writing the optional Zip comment
zipBuffer - a ZipBuffer instance used to convert integer values to Zip variants
Throws:
java.io.IOException - if an I/O error occurred

getBytes

protected static byte[] getBytes(java.lang.String name,
                                 java.lang.String encoding)
                          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
encoding - the encoding the string is encoded with
Returns:
the bytes as a byte array
Throws:
java.util.zip.ZipException - on error

adjustToLong

protected static long adjustToLong(int i)
Returns a long that is the unsigned intepretation of the given (signed) int.

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

write

public void write(byte[] b,
                  int offset,
                  int length)
           throws java.io.IOException
Writes the given bytes to the current Zip entry opened with putNextEntry(ZipEntry), using the entry's compression method. If no entry is currently open, the bytes will be written as-is to the underlying OutputStream.

Overrides:
write in class java.io.OutputStream
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

write

public void write(byte[] b)
           throws java.io.IOException
Writes the given bytes to the current Zip entry opened with putNextEntry(ZipEntry), using the entry's compression method. If no entry is currently open, the bytes will be written as-is to the underlying OutputStream.

Overrides:
write in class java.io.OutputStream
Parameters:
b - the byte array to write
Throws:
java.io.IOException - on error

write

public void write(int b)
           throws java.io.IOException
Writes a single byte to the current Zip entry opened with putNextEntry(ZipEntry), using the entry's compression method. If no entry is currently open, the bytes will be written as-is to the underlying OutputStream.

Delegates to the three arg method.

Specified by:
write in class java.io.OutputStream
Parameters:
b - the byte 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.OutputStream
Throws:
java.io.IOException - if an I/O error occurs.

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.OutputStream
Throws:
java.io.IOException - if an I/O error occurs.


This file is part of muCommander - Copyright (C) 2002-2008 Maxence Bernard