Class ZipArchiveOutputStream
- java.lang.Object
-
- java.io.OutputStream
-
- org.apache.commons.compress.archivers.ArchiveOutputStream
-
- org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
-
- All Implemented Interfaces:
java.io.Closeable
,java.io.Flushable
,java.lang.AutoCloseable
- Direct Known Subclasses:
JarArchiveOutputStream
public class ZipArchiveOutputStream extends ArchiveOutputStream
Reimplementation ofjava.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
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, this means, you don't need to calculate them yourself. Unfortunately this is not possible for theSTORED
method, here setting the CRC and uncompressed size information is required beforeputArchiveEntry(ArchiveEntry)
can be called.As of Apache Commons Compress 1.3 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.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.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
ZipArchiveOutputStream.UnicodeExtraFieldPolicy
enum that represents the possible policies for creating Unicode extra fields.
-
Field Summary
Fields Modifier and Type Field Description static int
DEFAULT_COMPRESSION
Default compression level for deflated entries.static int
DEFLATED
Compression method for deflated entries.static int
EFS_FLAG
Deprecated.useGeneralPurposeBit.UFT8_NAMES_FLAG
insteadstatic int
STORED
Compression method for stored entries.
-
Constructor Summary
Constructors Constructor Description ZipArchiveOutputStream(java.io.File file)
Creates a new ZIP OutputStream writing to a File.ZipArchiveOutputStream(java.io.File file, long zipSplitSize)
Creates a split ZIP Archive.ZipArchiveOutputStream(java.io.OutputStream out)
Creates a new ZIP OutputStream filtering the underlying stream.ZipArchiveOutputStream(java.nio.channels.SeekableByteChannel channel)
Creates a new ZIP OutputStream writing to a SeekableByteChannel.ZipArchiveOutputStream(java.nio.file.Path file, java.nio.file.OpenOption... options)
Creates a new ZIP OutputStream writing to a Path.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addRawArchiveEntry(ZipArchiveEntry entry, java.io.InputStream rawStream)
Adds an archive entry with a raw input stream.boolean
canWriteEntryData(ArchiveEntry 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
closeArchiveEntry()
Writes all necessary data for this entry.ArchiveEntry
createArchiveEntry(java.io.File inputFile, java.lang.String entryName)
Creates a new zip entry taking some information from the given file and using the provided name.ArchiveEntry
createArchiveEntry(java.nio.file.Path inputPath, java.lang.String entryName, java.nio.file.LinkOption... options)
Creates a new zip entry taking some information from the given file and using the provided name.void
finish()
Finishes the addition of entries to this stream, without closing it.void
flush()
Flushes this output stream and forces any buffered output bytes to be written out to the stream.java.lang.String
getEncoding()
The encoding to use for file names 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
putArchiveEntry(ArchiveEntry archiveEntry)
Writes the headers for an archive entry to the output stream.void
setComment(java.lang.String comment)
Set the file comment.void
setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy b)
Whether to create Unicode Extra Fields.void
setEncoding(java.lang.String encoding)
The encoding to use for file names 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.void
write(byte[] b, int offset, int length)
Writes bytes to ZIP entry.void
writePreamble(byte[] preamble)
Write preamble data.void
writePreamble(byte[] preamble, int offset, int length)
Write preamble data.-
Methods inherited from class org.apache.commons.compress.archivers.ArchiveOutputStream
getBytesWritten, getCount, write
-
-
-
-
Field Detail
-
DEFLATED
public static final int DEFLATED
Compression method for deflated entries.- See Also:
- Constant Field Values
-
DEFAULT_COMPRESSION
public static final int DEFAULT_COMPRESSION
Default compression level for deflated entries.- See Also:
- Constant Field Values
-
STORED
public static final int STORED
Compression method for stored entries.- See Also:
- Constant Field Values
-
EFS_FLAG
@Deprecated public static final int EFS_FLAG
Deprecated.useGeneralPurposeBit.UFT8_NAMES_FLAG
insteadGeneral purpose flag, which indicates that file names are written in UTF-8.- See Also:
- Constant Field Values
-
-
Constructor Detail
-
ZipArchiveOutputStream
public ZipArchiveOutputStream(java.io.OutputStream out)
Creates a new ZIP OutputStream filtering the underlying stream.- Parameters:
out
- the outputstream to zip
-
ZipArchiveOutputStream
public ZipArchiveOutputStream(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
-
ZipArchiveOutputStream
public ZipArchiveOutputStream(java.nio.file.Path file, java.nio.file.OpenOption... options) throws java.io.IOException
Creates a new ZIP OutputStream writing to a Path. Will use random access if possible.- Parameters:
file
- the file to zip tooptions
- options specifying how the file is opened.- Throws:
java.io.IOException
- on error- Since:
- 1.21
-
ZipArchiveOutputStream
public ZipArchiveOutputStream(java.io.File file, long zipSplitSize) throws java.io.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 archivezipSplitSize
- maximum size of a single part of the split archive created by this stream. Must be between 64kB and about 4GB.- Throws:
java.io.IOException
- on errorjava.lang.IllegalArgumentException
- if zipSplitSize is not in the required range- Since:
- 1.20
-
ZipArchiveOutputStream
public ZipArchiveOutputStream(java.nio.channels.SeekableByteChannel channel) throws java.io.IOException
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- Throws:
java.io.IOException
- on error- Since:
- 1.13
-
-
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 invokingputArchiveEntry(ArchiveEntry)
.- Returns:
- true if seekable
-
setEncoding
public void setEncoding(java.lang.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
-
getEncoding
public java.lang.String getEncoding()
The encoding to use for file names and the file comment.- Returns:
- null if using the platform's default character encoding.
-
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
-
setCreateUnicodeExtraFields
public void setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy b)
Whether to create Unicode Extra Fields.Defaults to NEVER.
- Parameters:
b
- whether to create Unicode Extra Fields.
-
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.
-
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()
orclose()
may throw aZip64RequiredException
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 theZipArchiveEntry
is known when callingputArchiveEntry(org.apache.commons.compress.archivers.ArchiveEntry)
or the archive is written to a seekable output (i.e. you have used theFile-arg constructor
) - this mode is not valid when the output stream is not seekable and the uncompressed size is unknown whenputArchiveEntry(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 toNever
otherwise.Always
will create an archive that is at least 24 bytes per entry bigger than the oneNever
would create.Defaults to
AsNeeded
unlessputArchiveEntry(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 isNever
.- Parameters:
mode
- Whether Zip64 extensions will be used.- Since:
- 1.3
-
finish
public void finish() throws java.io.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 classArchiveOutputStream
- Throws:
Zip64RequiredException
- if the archive's size exceeds 4 GByte or there are more than 65535 entries inside the archive andsetUseZip64(org.apache.commons.compress.archivers.zip.Zip64Mode)
isZip64Mode.Never
.java.io.IOException
- if the user forgets to close the entry.
-
closeArchiveEntry
public void closeArchiveEntry() throws java.io.IOException
Writes all necessary data for this entry.- Specified by:
closeArchiveEntry
in classArchiveOutputStream
- Throws:
java.io.IOException
- on errorZip64RequiredException
- if the entry's uncompressed or compressed size exceeds 4 GByte andsetUseZip64(org.apache.commons.compress.archivers.zip.Zip64Mode)
isZip64Mode.Never
.
-
addRawArchiveEntry
public void addRawArchiveEntry(ZipArchiveEntry entry, java.io.InputStream rawStream) throws java.io.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 addrawStream
- The raw input stream of a different entry. May be compressed/encrypted.- Throws:
java.io.IOException
- If copying fails
-
putArchiveEntry
public void putArchiveEntry(ArchiveEntry archiveEntry) throws java.io.IOException
Writes the headers for an archive entry to the output stream. The caller must then write the content to the stream and callArchiveOutputStream.closeArchiveEntry()
to complete the process.- Specified by:
putArchiveEntry
in classArchiveOutputStream
- Parameters:
archiveEntry
- describes the entry- Throws:
java.lang.ClassCastException
- if entry is not an instance of ZipArchiveEntryZip64RequiredException
- if the entry's uncompressed or compressed size is known to exceed 4 GByte andsetUseZip64(org.apache.commons.compress.archivers.zip.Zip64Mode)
isZip64Mode.Never
.java.io.IOException
- if an I/O error occurs
-
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.
-
setMethod
public void setMethod(int method)
Sets the default compression method for subsequent entries.Default is DEFLATED.
- Parameters:
method
- anint
from java.util.zip.ZipEntry
-
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 classArchiveOutputStream
- Parameters:
ae
- the entry to test- Returns:
- This implementation always returns true.
- Since:
- 1.1
-
writePreamble
public void writePreamble(byte[] preamble) throws java.io.IOException
Write preamble data. For most of time, this is used to make self-extracting zips.- Parameters:
preamble
- data to write- Throws:
java.io.IOException
- if an entry already exists- Since:
- 1.21
-
writePreamble
public void writePreamble(byte[] preamble, int offset, int length) throws java.io.IOException
Write preamble data. For most of time, this is used to make self-extracting zips.- Parameters:
preamble
- data to writeoffset
- the start offset in the datalength
- the number of bytes to write- Throws:
java.io.IOException
- if an entry already exists- Since:
- 1.21
-
write
public void write(byte[] b, int offset, int length) throws java.io.IOException
Writes bytes to ZIP entry.- Overrides:
write
in classjava.io.OutputStream
- Parameters:
b
- the byte array to writeoffset
- the start position to write fromlength
- 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 interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.io.Closeable
- Overrides:
close
in classjava.io.OutputStream
- 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 andsetUseZip64(org.apache.commons.compress.archivers.zip.Zip64Mode)
isZip64Mode.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 interfacejava.io.Flushable
- Overrides:
flush
in classjava.io.OutputStream
- Throws:
java.io.IOException
- if an I/O error occurs.
-
createArchiveEntry
public ArchiveEntry createArchiveEntry(java.io.File inputFile, java.lang.String entryName) throws java.io.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 classArchiveOutputStream
- Parameters:
inputFile
- the file to create the entry fromentryName
- name to use for the entry- Returns:
- the ArchiveEntry set up with details from the file
- Throws:
java.io.IOException
- if an I/O error occurs
-
createArchiveEntry
public ArchiveEntry createArchiveEntry(java.nio.file.Path inputPath, java.lang.String entryName, java.nio.file.LinkOption... options) throws java.io.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 classArchiveOutputStream
- 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:
java.io.IOException
- if an I/O error occurs.- Since:
- 1.21
-
-