Class ZipArchiveOutputStream

java.lang.Object
java.io.OutputStream
org.apache.commons.compress.archivers.ArchiveOutputStream
org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
All Implemented Interfaces:
Closeable, Flushable, AutoCloseable
Direct Known Subclasses:
JarArchiveOutputStream

public class ZipArchiveOutputStream extends ArchiveOutputStream
Reimplementation of java.util.zip.ZipOutputStream to 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 SeekableByteChannel when it knows that the output is going to go to a file and no split archive shall be created.

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

As of Apache Commons Compress 1.3, the class 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.commons.compress.archivers.zip.Zip64Mode). If the stream can not use SeekableByteChannel and you try to write a ZipArchiveEntry of unknown size, then Zip64 extensions will be disabled by default.

  • Field Details

  • Constructor Details

    • ZipArchiveOutputStream

      public ZipArchiveOutputStream(File file) throws IOException
      Creates a new ZIP OutputStream writing to a File. Will use random access if possible.
      Parameters:
      file - the file to ZIP to
      Throws:
      IOException - on error
    • ZipArchiveOutputStream

      public ZipArchiveOutputStream(File file, long zipSplitSize) throws IOException
      Creates a split ZIP Archive.

      The files making up the archive will use Z01, Z02, ... extensions and the last part of it will be the given file.

      Even though the stream writes to a file this stream will behave as if no random access was possible. This means the sizes of stored entries need to be known before the actual entry data is written.

      Parameters:
      file - the file that will become the last part of the split archive
      zipSplitSize - maximum size of a single part of the split archive created by this stream. Must be between 64kB and about 4GB.
      Throws:
      IOException - on error
      IllegalArgumentException - if zipSplitSize is not in the required range
      Since:
      1.20
    • ZipArchiveOutputStream

      public ZipArchiveOutputStream(OutputStream out)
      Creates a new ZIP OutputStream filtering the underlying stream.
      Parameters:
      out - the outputstream to zip
    • ZipArchiveOutputStream

      public ZipArchiveOutputStream(Path path, long zipSplitSize) throws IOException
      Creates a split ZIP Archive.

      The files making up the archive will use Z01, Z02, ... extensions and the last part of it will be the given file.

      Even though the stream writes to a file this stream will behave as if no random access was possible. This means the sizes of stored entries need to be known before the actual entry data is written.

      Parameters:
      path - the path to the file that will become the last part of the split archive
      zipSplitSize - maximum size of a single part of the split archive created by this stream. Must be between 64kB and about 4GB.
      Throws:
      IOException - on error
      IllegalArgumentException - if zipSplitSize is not in the required range
      Since:
      1.22
    • ZipArchiveOutputStream

      public ZipArchiveOutputStream(Path file, OpenOption... options) throws IOException
      Creates a new ZIP OutputStream writing to a Path. Will use random access if possible.
      Parameters:
      file - the file to ZIP to
      options - options specifying how the file is opened.
      Throws:
      IOException - on error
      Since:
      1.21
    • ZipArchiveOutputStream

      public ZipArchiveOutputStream(SeekableByteChannel channel)
      Creates a new ZIP OutputStream writing to a SeekableByteChannel.

      SeekableInMemoryByteChannel allows you to write to an in-memory archive using random access.

      Parameters:
      channel - the channel to ZIP to
      Since:
      1.13
  • Method Details

    • addRawArchiveEntry

      public void addRawArchiveEntry(ZipArchiveEntry entry, InputStream rawStream) throws IOException
      Adds an archive entry with a raw input stream. If crc, size and compressed size are supplied on the entry, these values will be used as-is. Zip64 status is re-established based on the settings in this stream, and the supplied value is ignored. The entry is put and closed immediately.
      Parameters:
      entry - The archive entry to add
      rawStream - The raw input stream of a different entry. May be compressed/encrypted.
      Throws:
      IOException - If copying fails
    • canWriteEntryData

      public boolean canWriteEntryData(ArchiveEntry 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.

      Overrides:
      canWriteEntryData in class ArchiveOutputStream
      Parameters:
      ae - the entry to test
      Returns:
      This implementation always returns true.
      Since:
      1.1
    • close

      public void close() throws IOException
      Closes this output stream and releases any system resources associated with the stream.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Overrides:
      close in class OutputStream
      Throws:
      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.commons.compress.archivers.zip.Zip64Mode) is Zip64Mode.Never.
    • closeArchiveEntry

      public void closeArchiveEntry() throws IOException
      Writes all necessary data for this entry.
      Specified by:
      closeArchiveEntry in class ArchiveOutputStream
      Throws:
      IOException - on error
      Zip64RequiredException - if the entry's uncompressed or compressed size exceeds 4 GByte and setUseZip64(org.apache.commons.compress.archivers.zip.Zip64Mode) is Zip64Mode.Never.
    • createArchiveEntry

      public ArchiveEntry createArchiveEntry(File inputFile, String entryName) throws IOException
      Creates a new ZIP entry taking some information from the given file and using the provided name.

      The name will be adjusted to end with a forward slash "/" if the file is a directory. If the file is not a directory a potential trailing forward slash will be stripped from the entry name.

      Must not be used if the stream has already been closed.

      Specified by:
      createArchiveEntry in class ArchiveOutputStream
      Parameters:
      inputFile - the file to create the entry from
      entryName - name to use for the entry
      Returns:
      the ArchiveEntry set up with details from the file
      Throws:
      IOException - if an I/O error occurs
    • createArchiveEntry

      public ArchiveEntry createArchiveEntry(Path inputPath, String entryName, LinkOption... options) throws IOException
      Creates a new ZIP entry taking some information from the given file and using the provided name.

      The name will be adjusted to end with a forward slash "/" if the file is a directory. If the file is not a directory a potential trailing forward slash will be stripped from the entry name.

      Must not be used if the stream has already been closed.

      Overrides:
      createArchiveEntry in class ArchiveOutputStream
      Parameters:
      inputPath - path to create the entry from.
      entryName - name of the entry.
      options - options indicating how symbolic links are handled.
      Returns:
      a new instance.
      Throws:
      IOException - if an I/O error occurs.
      Since:
      1.21
    • finish

      public void finish() throws IOException
      Finishes the addition of entries to this stream, without closing it. Additional data can be written, if the format supports it.
      Specified by:
      finish in class ArchiveOutputStream
      Throws:
      Zip64RequiredException - if the archive's size exceeds 4 GByte or there are more than 65535 entries inside the archive and setUseZip64(org.apache.commons.compress.archivers.zip.Zip64Mode) is Zip64Mode.Never.
      IOException - if the user forgets to close the entry.
    • flush

      public void flush() throws IOException
      Flushes this output stream and forces any buffered output bytes to be written out to the stream.
      Specified by:
      flush in interface Flushable
      Overrides:
      flush in class OutputStream
      Throws:
      IOException - if an I/O error occurs.
    • getBytesWritten

      public long getBytesWritten()
      Returns the total number of bytes written to this stream.
      Overrides:
      getBytesWritten in class ArchiveOutputStream
      Returns:
      the number of written bytes
      Since:
      1.22
    • getEncoding

      public String getEncoding()
      The encoding to use for file names and the file comment.
      Returns:
      null if using the platform's default character encoding.
    • 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 putArchiveEntry(ArchiveEntry).

      Returns:
      true if seekable
    • putArchiveEntry

      public void putArchiveEntry(ArchiveEntry archiveEntry) throws IOException
      Writes the headers for an archive entry to the output stream. The caller must then write the content to the stream and call ArchiveOutputStream.closeArchiveEntry() to complete the process.
      Specified by:
      putArchiveEntry in class ArchiveOutputStream
      Parameters:
      archiveEntry - describes the entry
      Throws:
      ClassCastException - if entry is not an instance of ZipArchiveEntry
      Zip64RequiredException - if the entry's uncompressed or compressed size is known to exceed 4 GByte and setUseZip64(org.apache.commons.compress.archivers.zip.Zip64Mode) is Zip64Mode.Never.
      IOException - if an I/O error occurs
    • setComment

      public void setComment(String comment)
      Set the file comment.
      Parameters:
      comment - the comment
    • setCreateUnicodeExtraFields

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

      Defaults to NEVER.

      Parameters:
      b - whether to create Unicode Extra Fields.
    • setEncoding

      public void setEncoding(String encoding)
      The encoding to use for file names 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 UTF-8.

      Parameters:
      encoding - the encoding to use for file names, use null for the platform's default encoding
    • 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.

      Parameters:
      b - whether to fall back to UTF and the language encoding flag if the file name cannot be encoded using the specified encoding.
    • setLevel

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

      Default is Deflater.DEFAULT_COMPRESSION.

      Parameters:
      level - the compression level.
      Throws:
      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
    • setUseLanguageEncodingFlag

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

      Defaults to true.

      Parameters:
      b - whether to set the language encoding flag if the file name encoding is UTF-8
    • setUseZip64

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

      When setting the mode to Never, putArchiveEntry(org.apache.commons.compress.archivers.ArchiveEntry), closeArchiveEntry(), 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 ZipArchiveEntry is known when calling putArchiveEntry(org.apache.commons.compress.archivers.ArchiveEntry) 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 putArchiveEntry(org.apache.commons.compress.archivers.ArchiveEntry) 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 putArchiveEntry(org.apache.commons.compress.archivers.ArchiveEntry) is called with an entry of unknown size and data is written to a non-seekable stream - in this case the default is Never.

      Parameters:
      mode - Whether Zip64 extensions will be used.
      Since:
      1.3
    • write

      public void write(byte[] b, int offset, int length) throws IOException
      Writes bytes to ZIP entry.
      Overrides:
      write in class OutputStream
      Parameters:
      b - the byte array to write
      offset - the start position to write from
      length - the number of bytes to write
      Throws:
      IOException - on error
    • writePreamble

      public void writePreamble(byte[] preamble) throws IOException
      Write preamble data. For most of the time, this is used to make self-extracting zips.
      Parameters:
      preamble - data to write
      Throws:
      IOException - if an entry already exists
      Since:
      1.21
    • writePreamble

      public void writePreamble(byte[] preamble, int offset, int length) throws IOException
      Write preamble data. For most of the time, this is used to make self-extracting zips.
      Parameters:
      preamble - data to write
      offset - the start offset in the data
      length - the number of bytes to write
      Throws:
      IOException - if an entry already exists
      Since:
      1.21