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.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 private static class
ZipArchiveOutputStream.CurrentEntry
Structure collecting information for the entry that is currently being written.private static class
ZipArchiveOutputStream.EntryMetaData
static class
ZipArchiveOutputStream.UnicodeExtraFieldPolicy
enum that represents the possible policies for creating Unicode extra fields.
-
Field Summary
Fields Modifier and Type Field Description (package private) static int
BUFFER_SIZE
private java.util.Calendar
calendarInstance
private long
cdLength
Length of central directory.private long
cdOffset
Start of central directory.private static int
CFH_COMMENT_LENGTH_OFFSET
private static int
CFH_COMPRESSED_SIZE_OFFSET
private static int
CFH_CRC_OFFSET
private static int
CFH_DISK_NUMBER_OFFSET
private static int
CFH_EXTERNAL_ATTRIBUTES_OFFSET
private static int
CFH_EXTRA_LENGTH_OFFSET
private static int
CFH_FILENAME_LENGTH_OFFSET
private static int
CFH_FILENAME_OFFSET
private static int
CFH_GPB_OFFSET
private static int
CFH_INTERNAL_ATTRIBUTES_OFFSET
private static int
CFH_LFH_OFFSET
private static int
CFH_METHOD_OFFSET
private static int
CFH_ORIGINAL_SIZE_OFFSET
(package private) static byte[]
CFH_SIG
central file header signatureprivate static int
CFH_SIG_OFFSET
private static int
CFH_TIME_OFFSET
private static int
CFH_VERSION_MADE_BY_OFFSET
private static int
CFH_VERSION_NEEDED_OFFSET
private java.nio.channels.SeekableByteChannel
channel
Optional random access output.private java.lang.String
comment
The file comment.private byte[]
copyBuffer
private ZipArchiveOutputStream.UnicodeExtraFieldPolicy
createUnicodeExtraFields
whether to create UnicodePathExtraField-s for each entry.(package private) static byte[]
DD_SIG
data descriptor signatureprotected java.util.zip.Deflater
def
This Deflater object is used for output.static int
DEFAULT_COMPRESSION
Default compression level for deflated entries.(package private) static java.lang.String
DEFAULT_ENCODING
default encoding for file names and comment.static int
DEFLATED
Compression method for deflated entries.static int
EFS_FLAG
Deprecated.useGeneralPurposeBit.UFT8_NAMES_FLAG
insteadprivate static byte[]
EMPTY
private java.lang.String
encoding
The encoding to use for file names and the file comment.private java.util.List<ZipArchiveEntry>
entries
List of ZipArchiveEntries written so far.private ZipArchiveOutputStream.CurrentEntry
entry
Current entry.(package private) static byte[]
EOCD_SIG
end of central dir signatureprivate boolean
fallbackToUTF8
Whether to encode non-encodable file names as UTF-8.protected boolean
finished
indicates if this archive is finished.private boolean
hasCompressionLevelChanged
Has the compression level changed when compared to the last entry?private boolean
hasUsedZip64
Whether anything inside this archive has used a ZIP64 feature.private int
level
Compression level for next entry.private static int
LFH_COMPRESSED_SIZE_OFFSET
private static int
LFH_CRC_OFFSET
private static int
LFH_EXTRA_LENGTH_OFFSET
private static int
LFH_FILENAME_LENGTH_OFFSET
private static int
LFH_FILENAME_OFFSET
private static int
LFH_GPB_OFFSET
private static int
LFH_METHOD_OFFSET
private static int
LFH_ORIGINAL_SIZE_OFFSET
(package private) static byte[]
LFH_SIG
local file header signatureprivate static int
LFH_SIG_OFFSET
private static int
LFH_TIME_OFFSET
private static int
LFH_VERSION_NEEDED_OFFSET
private static byte[]
LZERO
Helper, a 0 as ZipLong.private java.util.Map<ZipArchiveEntry,ZipArchiveOutputStream.EntryMetaData>
metaData
Holds some book-keeping data for each entry.private int
method
Default compression method for next entry.private static byte[]
ONE
private java.io.OutputStream
out
static int
STORED
Compression method for stored entries.private StreamCompressor
streamCompressor
private boolean
useUTF8Flag
whether to use the general purpose bit flag when writing UTF-8 file names or not.private static byte[]
ZERO
Helper, a 0 as ZipShort.(package private) static byte[]
ZIP64_EOCD_LOC_SIG
ZIP64 end of central dir locator signature(package private) static byte[]
ZIP64_EOCD_SIG
ZIP64 end of central dir signatureprivate Zip64Mode
zip64Mode
private ZipEncoding
zipEncoding
The zip encoding to use for file names and the file comment.
-
Constructor Summary
Constructors Constructor Description ZipArchiveOutputStream(java.io.File file)
Creates a new ZIP OutputStream writing to a File.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.
-
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.private void
addUnicodeExtraFields(ZipArchiveEntry ze, boolean encodable, java.nio.ByteBuffer name)
Adds UnicodeExtra fields for name and file comment if mode is ALWAYS or the data cannot be encoded using the configured encoding.boolean
canWriteEntryData(ArchiveEntry ae)
Whether this stream is able to write the given entry.private boolean
checkIfNeedsZip64(Zip64Mode effectiveMode)
Verifies the sizes aren't too big in the Zip64Mode.Never case and returns whether the entry would require a Zip64 extra field.void
close()
Closes this output stream and releases any system resources associated with the stream.void
closeArchiveEntry()
Writes all necessary data for this entry.private void
closeCopiedEntry(boolean phased)
Writes all necessary data for this entry.private void
closeEntry(boolean actuallyNeedsZip64, boolean phased)
private void
copyFromZipInputStream(java.io.InputStream src)
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.private byte[]
createCentralFileHeader(ZipArchiveEntry ze)
private byte[]
createCentralFileHeader(ZipArchiveEntry ze, java.nio.ByteBuffer name, ZipArchiveOutputStream.EntryMetaData entryMetaData, boolean needsZip64Extra)
Writes the central file header entry.private byte[]
createLocalFileHeader(ZipArchiveEntry ze, java.nio.ByteBuffer name, boolean encodable, boolean phased, long archiveOffset)
protected void
deflate()
Writes next block of compressed data to the output stream.(package private) void
destroy()
Closes the underlying stream/file without finishing the archive, the result will likely be a corrupt archive.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.private void
flushDeflater()
Ensures all bytes sent to the deflater are written to the stream.private Zip64Mode
getEffectiveZip64Mode(ZipArchiveEntry ze)
If the mode is AsNeeded and the entry is a compressed entry of unknown size that gets written to a non-seekable stream then change the default to Never.java.lang.String
getEncoding()
The encoding to use for file names and the file comment.private ZipEncoding
getEntryEncoding(ZipArchiveEntry ze)
private GeneralPurposeBit
getGeneralPurposeBits(boolean utfFallback, boolean usesDataDescriptor)
private java.nio.ByteBuffer
getName(ZipArchiveEntry ze)
private Zip64ExtendedInformationExtraField
getZip64Extra(ZipArchiveEntry ze)
Get the existing ZIP64 extended information extra field or create a new one and add it to the entry.private boolean
handleSizesAndCrc(long bytesWritten, long crc, Zip64Mode effectiveMode)
Ensures the current entry's size and CRC information is set to the values just written, verifies it isn't too big in the Zip64Mode.Never case and returns whether the entry would require a Zip64 extra field.private void
handleZip64Extra(ZipArchiveEntry ze, long lfhOffset, boolean needsZip64Extra)
If the entry needs Zip64 extra information inside the central directory then configure its data.private boolean
hasZip64Extra(ZipArchiveEntry ze)
Is there a ZIP64 extended information extra field for the entry?boolean
isSeekable()
This method indicates whether this archive is writing to a seekable stream (i.e., to a random access file).private boolean
isTooLageForZip32(ZipArchiveEntry zipArchiveEntry)
private boolean
isZip64Required(ZipArchiveEntry entry1, Zip64Mode requestedMode)
private void
preClose()
void
putArchiveEntry(ArchiveEntry archiveEntry)
Writes the headers for an archive entry to the output stream.private void
putArchiveEntry(ArchiveEntry archiveEntry, boolean phased)
Writes the headers for an archive entry to the output stream.private void
rewriteSizesAndCrc(boolean actuallyNeedsZip64)
When using random access output, write the local file header and potentiall the ZIP64 extra containing the correct CRC and compressed/uncompressed sizes.void
setComment(java.lang.String comment)
Set the file comment.void
setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy b)
Whether to create Unicode Extra Fields.private void
setDefaults(ZipArchiveEntry entry)
Provides default values for compression method and last modification time.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.private boolean
shouldAddZip64Extra(ZipArchiveEntry entry, Zip64Mode mode)
Whether to addd a Zip64 extended information extra field to the local file header.private boolean
usesDataDescriptor(int zipMethod, boolean phased)
private void
validateSizeInformation(Zip64Mode effectiveMode)
Throws an exception if the size is unknown for a stored entry that is written to a non-seekable output or the entry is too big to be written without Zip64 extra but the mode has been set to Never.private int
versionNeededToExtract(int zipMethod, boolean zip64, boolean usedDataDescriptor)
private int
versionNeededToExtractMethod(int zipMethod)
void
write(byte[] b, int offset, int length)
Writes bytes to ZIP entry.protected void
writeCentralDirectoryEnd()
Writes the "End of central dir record".private void
writeCentralDirectoryInChunks()
protected void
writeCentralFileHeader(ZipArchiveEntry ze)
Writes the central file header entry.private void
writeCounted(byte[] data)
Write bytes to output or random access file.protected void
writeDataDescriptor(ZipArchiveEntry ze)
Writes the data descriptor entry.protected void
writeLocalFileHeader(ZipArchiveEntry ze)
Writes the local file header entryprivate void
writeLocalFileHeader(ZipArchiveEntry ze, boolean phased)
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 org.apache.commons.compress.archivers.ArchiveOutputStream
count, count, getBytesWritten, getCount, write
-
-
-
-
Field Detail
-
BUFFER_SIZE
static final int BUFFER_SIZE
- See Also:
- Constant Field Values
-
LFH_SIG_OFFSET
private static final int LFH_SIG_OFFSET
- See Also:
- Constant Field Values
-
LFH_VERSION_NEEDED_OFFSET
private static final int LFH_VERSION_NEEDED_OFFSET
- See Also:
- Constant Field Values
-
LFH_GPB_OFFSET
private static final int LFH_GPB_OFFSET
- See Also:
- Constant Field Values
-
LFH_METHOD_OFFSET
private static final int LFH_METHOD_OFFSET
- See Also:
- Constant Field Values
-
LFH_TIME_OFFSET
private static final int LFH_TIME_OFFSET
- See Also:
- Constant Field Values
-
LFH_CRC_OFFSET
private static final int LFH_CRC_OFFSET
- See Also:
- Constant Field Values
-
LFH_COMPRESSED_SIZE_OFFSET
private static final int LFH_COMPRESSED_SIZE_OFFSET
- See Also:
- Constant Field Values
-
LFH_ORIGINAL_SIZE_OFFSET
private static final int LFH_ORIGINAL_SIZE_OFFSET
- See Also:
- Constant Field Values
-
LFH_FILENAME_LENGTH_OFFSET
private static final int LFH_FILENAME_LENGTH_OFFSET
- See Also:
- Constant Field Values
-
LFH_EXTRA_LENGTH_OFFSET
private static final int LFH_EXTRA_LENGTH_OFFSET
- See Also:
- Constant Field Values
-
LFH_FILENAME_OFFSET
private static final int LFH_FILENAME_OFFSET
- See Also:
- Constant Field Values
-
CFH_SIG_OFFSET
private static final int CFH_SIG_OFFSET
- See Also:
- Constant Field Values
-
CFH_VERSION_MADE_BY_OFFSET
private static final int CFH_VERSION_MADE_BY_OFFSET
- See Also:
- Constant Field Values
-
CFH_VERSION_NEEDED_OFFSET
private static final int CFH_VERSION_NEEDED_OFFSET
- See Also:
- Constant Field Values
-
CFH_GPB_OFFSET
private static final int CFH_GPB_OFFSET
- See Also:
- Constant Field Values
-
CFH_METHOD_OFFSET
private static final int CFH_METHOD_OFFSET
- See Also:
- Constant Field Values
-
CFH_TIME_OFFSET
private static final int CFH_TIME_OFFSET
- See Also:
- Constant Field Values
-
CFH_CRC_OFFSET
private static final int CFH_CRC_OFFSET
- See Also:
- Constant Field Values
-
CFH_COMPRESSED_SIZE_OFFSET
private static final int CFH_COMPRESSED_SIZE_OFFSET
- See Also:
- Constant Field Values
-
CFH_ORIGINAL_SIZE_OFFSET
private static final int CFH_ORIGINAL_SIZE_OFFSET
- See Also:
- Constant Field Values
-
CFH_FILENAME_LENGTH_OFFSET
private static final int CFH_FILENAME_LENGTH_OFFSET
- See Also:
- Constant Field Values
-
CFH_EXTRA_LENGTH_OFFSET
private static final int CFH_EXTRA_LENGTH_OFFSET
- See Also:
- Constant Field Values
-
CFH_COMMENT_LENGTH_OFFSET
private static final int CFH_COMMENT_LENGTH_OFFSET
- See Also:
- Constant Field Values
-
CFH_DISK_NUMBER_OFFSET
private static final int CFH_DISK_NUMBER_OFFSET
- See Also:
- Constant Field Values
-
CFH_INTERNAL_ATTRIBUTES_OFFSET
private static final int CFH_INTERNAL_ATTRIBUTES_OFFSET
- See Also:
- Constant Field Values
-
CFH_EXTERNAL_ATTRIBUTES_OFFSET
private static final int CFH_EXTERNAL_ATTRIBUTES_OFFSET
- See Also:
- Constant Field Values
-
CFH_LFH_OFFSET
private static final int CFH_LFH_OFFSET
- See Also:
- Constant Field Values
-
CFH_FILENAME_OFFSET
private static final int CFH_FILENAME_OFFSET
- See Also:
- Constant Field Values
-
finished
protected boolean finished
indicates if this archive is finished. protected for use in Jar implementation
-
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
-
DEFAULT_ENCODING
static final java.lang.String DEFAULT_ENCODING
default encoding for file names and comment.- 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
-
EMPTY
private static final byte[] EMPTY
-
entry
private ZipArchiveOutputStream.CurrentEntry entry
Current entry.
-
comment
private java.lang.String comment
The file comment.
-
level
private int level
Compression level for next entry.
-
hasCompressionLevelChanged
private boolean hasCompressionLevelChanged
Has the compression level changed when compared to the last entry?
-
method
private int method
Default compression method for next entry.
-
entries
private final java.util.List<ZipArchiveEntry> entries
List of ZipArchiveEntries written so far.
-
streamCompressor
private final StreamCompressor streamCompressor
-
cdOffset
private long cdOffset
Start of central directory.
-
cdLength
private long cdLength
Length of central directory.
-
ZERO
private static final byte[] ZERO
Helper, a 0 as ZipShort.
-
LZERO
private static final byte[] LZERO
Helper, a 0 as ZipLong.
-
ONE
private static final byte[] ONE
-
metaData
private final java.util.Map<ZipArchiveEntry,ZipArchiveOutputStream.EntryMetaData> metaData
Holds some book-keeping data for each entry.
-
encoding
private 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.
-
zipEncoding
private ZipEncoding zipEncoding
The zip encoding to use for file names and the file comment. This field is of internal use and will be set insetEncoding(String)
.
-
def
protected final java.util.zip.Deflater def
This Deflater object is used for output.
-
channel
private final java.nio.channels.SeekableByteChannel channel
Optional random access output.
-
out
private final java.io.OutputStream out
-
useUTF8Flag
private boolean useUTF8Flag
whether to use the general purpose bit flag when writing UTF-8 file names or not.
-
fallbackToUTF8
private boolean fallbackToUTF8
Whether to encode non-encodable file names as UTF-8.
-
createUnicodeExtraFields
private ZipArchiveOutputStream.UnicodeExtraFieldPolicy createUnicodeExtraFields
whether to create UnicodePathExtraField-s for each entry.
-
hasUsedZip64
private boolean hasUsedZip64
Whether anything inside this archive has used a ZIP64 feature.- Since:
- 1.3
-
zip64Mode
private Zip64Mode zip64Mode
-
copyBuffer
private final byte[] copyBuffer
-
calendarInstance
private final java.util.Calendar calendarInstance
-
LFH_SIG
static final byte[] LFH_SIG
local file header signature
-
DD_SIG
static final byte[] DD_SIG
data descriptor signature
-
CFH_SIG
static final byte[] CFH_SIG
central file header signature
-
EOCD_SIG
static final byte[] EOCD_SIG
end of central dir signature
-
ZIP64_EOCD_SIG
static final byte[] ZIP64_EOCD_SIG
ZIP64 end of central dir signature
-
ZIP64_EOCD_LOC_SIG
static final byte[] ZIP64_EOCD_LOC_SIG
ZIP64 end of central dir locator signature
-
-
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.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.
-
writeCentralDirectoryInChunks
private void writeCentralDirectoryInChunks() throws java.io.IOException
- Throws:
java.io.IOException
-
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
.
-
closeCopiedEntry
private void closeCopiedEntry(boolean phased) throws java.io.IOException
Writes all necessary data for this entry.- Parameters:
phased
- This entry is second phase of a 2-phase zip creation, size, compressed size and crc are known in ZipArchiveEntry- 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
.
-
closeEntry
private void closeEntry(boolean actuallyNeedsZip64, boolean phased) throws java.io.IOException
- Throws:
java.io.IOException
-
preClose
private void preClose() throws java.io.IOException
- Throws:
java.io.IOException
-
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
-
flushDeflater
private void flushDeflater() throws java.io.IOException
Ensures all bytes sent to the deflater are written to the stream.- Throws:
java.io.IOException
-
handleSizesAndCrc
private boolean handleSizesAndCrc(long bytesWritten, long crc, Zip64Mode effectiveMode) throws java.util.zip.ZipException
Ensures the current entry's size and CRC information is set to the values just written, verifies it isn't too big in the Zip64Mode.Never case and returns whether the entry would require a Zip64 extra field.- Throws:
java.util.zip.ZipException
-
checkIfNeedsZip64
private boolean checkIfNeedsZip64(Zip64Mode effectiveMode) throws java.util.zip.ZipException
Verifies the sizes aren't too big in the Zip64Mode.Never case and returns whether the entry would require a Zip64 extra field.- Throws:
java.util.zip.ZipException
-
isZip64Required
private boolean isZip64Required(ZipArchiveEntry entry1, Zip64Mode requestedMode)
-
isTooLageForZip32
private boolean isTooLageForZip32(ZipArchiveEntry zipArchiveEntry)
-
rewriteSizesAndCrc
private void rewriteSizesAndCrc(boolean actuallyNeedsZip64) throws java.io.IOException
When using random access output, write the local file header and potentiall the ZIP64 extra containing the correct CRC and compressed/uncompressed sizes.- Throws:
java.io.IOException
-
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
-
putArchiveEntry
private void putArchiveEntry(ArchiveEntry archiveEntry, boolean phased) 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 callcloseArchiveEntry()
to complete the process.- Parameters:
archiveEntry
- The archiveEntryphased
- If true size, compressedSize and crc required to be known up-front in the archiveEntry- 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
-
setDefaults
private void setDefaults(ZipArchiveEntry entry)
Provides default values for compression method and last modification time.
-
validateSizeInformation
private void validateSizeInformation(Zip64Mode effectiveMode) throws java.util.zip.ZipException
Throws an exception if the size is unknown for a stored entry that is written to a non-seekable output or the entry is too big to be written without Zip64 extra but the mode has been set to Never.- Throws:
java.util.zip.ZipException
-
shouldAddZip64Extra
private boolean shouldAddZip64Extra(ZipArchiveEntry entry, Zip64Mode mode)
Whether to addd a Zip64 extended information extra field to the local file header.Returns true if
- mode is Always
- or we already know it is going to be needed
- or the size is unknown and we can ensure it won't hurt other implementations if we add it (i.e. we can erase its usage
-
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
-
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
-
writeCounted
private void writeCounted(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
-
copyFromZipInputStream
private void copyFromZipInputStream(java.io.InputStream src) throws java.io.IOException
- Throws:
java.io.IOException
-
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.
-
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
-
writeLocalFileHeader
protected void writeLocalFileHeader(ZipArchiveEntry ze) throws java.io.IOException
Writes the local file header entry- Parameters:
ze
- the entry to write- Throws:
java.io.IOException
- on error
-
writeLocalFileHeader
private void writeLocalFileHeader(ZipArchiveEntry ze, boolean phased) throws java.io.IOException
- Throws:
java.io.IOException
-
createLocalFileHeader
private byte[] createLocalFileHeader(ZipArchiveEntry ze, java.nio.ByteBuffer name, boolean encodable, boolean phased, long archiveOffset)
-
addUnicodeExtraFields
private void addUnicodeExtraFields(ZipArchiveEntry ze, boolean encodable, java.nio.ByteBuffer name) throws java.io.IOException
Adds UnicodeExtra fields for name and file comment if mode is ALWAYS or the data cannot be encoded using the configured encoding.- Throws:
java.io.IOException
-
writeDataDescriptor
protected void writeDataDescriptor(ZipArchiveEntry ze) throws java.io.IOException
Writes the data descriptor entry.- Parameters:
ze
- the entry to write- Throws:
java.io.IOException
- on error
-
writeCentralFileHeader
protected void writeCentralFileHeader(ZipArchiveEntry ze) throws java.io.IOException
Writes the central file header entry.- Parameters:
ze
- the entry to write- Throws:
java.io.IOException
- on errorZip64RequiredException
- if the archive's size exceeds 4 GByte and#setUseZip64
isZip64Mode.Never
.
-
createCentralFileHeader
private byte[] createCentralFileHeader(ZipArchiveEntry ze) throws java.io.IOException
- Throws:
java.io.IOException
-
createCentralFileHeader
private byte[] createCentralFileHeader(ZipArchiveEntry ze, java.nio.ByteBuffer name, ZipArchiveOutputStream.EntryMetaData entryMetaData, boolean needsZip64Extra) throws java.io.IOException
Writes the central file header entry.- Parameters:
ze
- the entry to writename
- The encoded nameentryMetaData
- meta data for this file- Throws:
java.io.IOException
- on error
-
handleZip64Extra
private void handleZip64Extra(ZipArchiveEntry ze, long lfhOffset, boolean needsZip64Extra)
If the entry needs Zip64 extra information inside the central directory then configure its data.
-
writeCentralDirectoryEnd
protected void writeCentralDirectoryEnd() throws java.io.IOException
Writes the "End of central dir record".- Throws:
java.io.IOException
- on errorZip64RequiredException
- if the archive's size exceeds 4 GByte or there are more than 65535 entries inside the archive and#setUseZip64
isZip64Mode.Never
.
-
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- Since:
- 1.3
-
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
-
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 writeoffset
- the start position to write fromlength
- the number of bytes to write- Throws:
java.io.IOException
- on error
-
getGeneralPurposeBits
private GeneralPurposeBit getGeneralPurposeBits(boolean utfFallback, boolean usesDataDescriptor)
-
versionNeededToExtract
private int versionNeededToExtract(int zipMethod, boolean zip64, boolean usedDataDescriptor)
-
usesDataDescriptor
private boolean usesDataDescriptor(int zipMethod, boolean phased)
-
versionNeededToExtractMethod
private int versionNeededToExtractMethod(int zipMethod)
-
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
-
getZip64Extra
private Zip64ExtendedInformationExtraField getZip64Extra(ZipArchiveEntry ze)
Get the existing ZIP64 extended information extra field or create a new one and add it to the entry.- Since:
- 1.3
-
hasZip64Extra
private boolean hasZip64Extra(ZipArchiveEntry ze)
Is there a ZIP64 extended information extra field for the entry?- Since:
- 1.3
-
getEffectiveZip64Mode
private Zip64Mode getEffectiveZip64Mode(ZipArchiveEntry ze)
If the mode is AsNeeded and the entry is a compressed entry of unknown size that gets written to a non-seekable stream then change the default to Never.- Since:
- 1.3
-
getEntryEncoding
private ZipEncoding getEntryEncoding(ZipArchiveEntry ze)
-
getName
private java.nio.ByteBuffer getName(ZipArchiveEntry ze) throws java.io.IOException
- Throws:
java.io.IOException
-
destroy
void destroy() throws java.io.IOException
Closes the underlying stream/file without finishing the archive, the result will likely be a corrupt archive.This method only exists to support tests that generate corrupt archives so they can clean up any temporary files.
- Throws:
java.io.IOException
-
-