TrueZIP Driver ZIP 7.1

de.schlichtherle.truezip.zip
Class RawZipFile<E extends ZipEntry>

java.lang.Object
  extended by de.schlichtherle.truezip.zip.RawZipFile<E>
All Implemented Interfaces:
Closeable, Iterable<E>
Direct Known Subclasses:
ZipFile, ZipInputShop

public abstract class RawZipFile<E extends ZipEntry>
extends Object
implements Iterable<E>, Closeable

Provides unsafe (raw) access to a ZIP file using unsynchronized methods and shared ZipEntry instances.

Warning: This class is not intended for public use - its API may change at will without prior notification!

Where the constructors of this class accept a charset parameter, this is used to decode comments and entry names in the ZIP file. However, if an entry has bit 11 set in its General Purpose Bit Flag, then this parameter is ignored and "UTF-8" is used for this entry. This is in accordance to Appendix D of PKWARE's ZIP File Format Specification, version 6.3.0 and later.

This class is able to skip a preamble like the one found in self extracting archives.

Author:
Christian Schlichtherle

Nested Class Summary
private  class RawZipFile.AccountedInputStream
          Accounts itself until it gets closed.
private static class RawZipFile.CheckedInputStream
          extends its super class to perform the check again the expected CRC from the entry provided to its constructor when close() is called.
private  class RawZipFile.IntervalInputStream
          InputStream that delegates requests to the underlying RandomAccessFile, making sure that only bytes from a certain range can be read.
private static class RawZipFile.IrregularOffsetMapper
          Adds a start value to the given offset.
(package private) static class RawZipFile.OffsetMapper
          Maps a given offset to a file pointer position.
private static class RawZipFile.PooledInflaterInputStream
          An input stream which uses a pooled inflater.
private static class RawZipFile.RawCheckedInputStream
          A stream which reads and returns deflated data from its input while a CRC-32 checksum is computed over the inflated data and checked in the method close.
private static class RawZipFile.SingletonReadOnlyFilePool
          A pool with a singleton read only file provided to its constructor.
 
Field Summary
private  ReadOnlyFile archive
          The nullable data source.
private  Charset charset
          The charset to use for entry names and comments.
private  String comment
          The comment of this ZIP file.
static Charset DEFAULT_CHARSET
          The default character set used for entry names and comments in ZIP files.
private  Map<String,E> entries
          Maps entry names to zip entries.
private  ZipEntryFactory<E> factory
           
private  long length
          The total number of bytes in this ZIP file.
private static int LFH_FILE_NAME_LENGTH_OFF
           
private  RawZipFile.OffsetMapper mapper
          Maps offsets specified in the ZIP file to real offsets in the file.
private  int openStreams
          The number of fetch streams reading from this ZIP file.
private  long postamble
          The number of bytes in the postamble of this ZIP file.
private  long preamble
          The number of bytes in the preamble of this ZIP file.
 
Constructor Summary
(package private) RawZipFile(Pool<ReadOnlyFile,IOException> source, Charset charset, boolean preambled, boolean postambled, ZipEntryFactory<E> factory)
           
protected RawZipFile(ReadOnlyFile archive, Charset charset, boolean preambled, boolean postambled, ZipEntryFactory<E> factory)
          Reads the given archive in order to provide random access to its ZIP entries.
 
Method Summary
(package private)  void assertOpen()
          Asserts that this ZIP file is still open for reading its entries.
 boolean busy()
          Returns true if and only if some input streams are busy with reading from this ZIP file.
 void close()
          Closes the file.
private  String decode(byte[] bytes)
           
private  int findCentralDirectory(ReadOnlyFile rof, boolean preambled, boolean postambled)
          Positions the file pointer at the first Central File Header.
private static int getBufferSize(ZipEntry entry)
           
 String getCharset()
          Returns the charset to use for entry names and the file comment.
 InputStream getCheckedInputStream(String name)
          Equivalent to getInputStream(name, true, true).
 InputStream getCheckedInputStream(ZipEntry entry)
          Equivalent to getInputStream(entry.getName(), true, true) instead.
 String getComment()
          Returns the comment of this ZIP file or null if no comment exists.
 E getEntry(String name)
          Returns the entry for the given name or null if no entry with this name exists.
 InputStream getInputStream(String name)
          Equivalent to getInputStream(name, false, true).
protected  InputStream getInputStream(String name, boolean check, boolean inflate)
          Returns an InputStream for reading the inflated or deflated data of the given entry.
 InputStream getInputStream(ZipEntry entry)
          Equivalent to getInputStream(entry.getName(), false, true) instead.
(package private)  RawZipFile.OffsetMapper getOffsetMapper()
           
 InputStream getPostambleInputStream()
          Returns an InputStream to read the postamble of this ZIP file.
 long getPostambleLength()
          Returns the length of the postamble of this ZIP file in bytes.
 InputStream getPreambleInputStream()
          Returns an InputStream to read the preamble of this ZIP file.
 long getPreambleLength()
          Returns the length of the preamble of this ZIP file in bytes.
 Iterator<E> iterator()
          Returns an iteration of all entries in this ZIP file.
 long length()
          Returns the file length of this ZIP file in bytes.
private  void mountCentralDirectory(ReadOnlyFile rof, boolean preambled, boolean postambled)
          Reads the central directory of the given file and populates the internal tables with ZipEntry instances.
 boolean offsetsConsiderPreamble()
          Returns true if and only if the offsets in this ZIP file are relative to the start of the file, rather than the first Local File Header.
private  void setComment(String comment)
           
 int size()
          Returns the number of entries in this ZIP file.
private static long skipWithBuffer(InputStream in, long toSkip, byte[] buf)
          This method skips toSkip bytes in the given input stream using the given buffer unless EOF or IOException.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

LFH_FILE_NAME_LENGTH_OFF

private static final int LFH_FILE_NAME_LENGTH_OFF
See Also:
Constant Field Values

DEFAULT_CHARSET

public static final Charset DEFAULT_CHARSET
The default character set used for entry names and comments in ZIP files. This is "UTF-8" for compatibility with Sun's JDK implementation. Note that you should use "IBM437" for ordinary ZIP files instead.


entries

private final Map<String,E extends ZipEntry> entries
Maps entry names to zip entries.


charset

private Charset charset
The charset to use for entry names and comments.


comment

private String comment
The comment of this ZIP file.


length

private long length
The total number of bytes in this ZIP file.


preamble

private long preamble
The number of bytes in the preamble of this ZIP file.


postamble

private long postamble
The number of bytes in the postamble of this ZIP file.


mapper

private RawZipFile.OffsetMapper mapper
Maps offsets specified in the ZIP file to real offsets in the file.


factory

private final ZipEntryFactory<E extends ZipEntry> factory

archive

private ReadOnlyFile archive
The nullable data source.


openStreams

private int openStreams
The number of fetch streams reading from this ZIP file.

Constructor Detail

RawZipFile

protected RawZipFile(@NonNull
                     ReadOnlyFile archive,
                     @NonNull
                     Charset charset,
                     boolean preambled,
                     boolean postambled,
                     @NonNull
                     ZipEntryFactory<E> factory)
              throws IOException
Reads the given archive in order to provide random access to its ZIP entries.

Parameters:
archive - the ReadOnlyFile instance to be read in order to provide random access to its ZIP entries.
charset - the charset to use for decoding entry names and ZIP file comment.
preambled - if this is true, then the ZIP file may have a preamble. Otherwise, the ZIP file must start with either a Local File Header (LFH) signature or an End Of Central Directory (EOCD) Header, causing this constructor to fail if the file is actually a false positive ZIP file, i.e. not compatible to the ZIP File Format Specification. This may be useful to read Self Extracting ZIP files (SFX), which usually contain the application code required for extraction in the preamble.
postambled - if this is true, then the ZIP file may have a postamble of arbitrary length. Otherwise, the ZIP file must not have a postamble which exceeds 64KB size, including the End Of Central Directory record (i.e. including the ZIP file comment), causing this constructor to fail if the file is actually a false positive ZIP file, i.e. not compatible to the ZIP File Format Specification. This may be useful to read Self Extracting ZIP files (SFX) with large postambles.
factory - a factory for ZipEntrys.
Throws:
NullPointerException - if any reference parameter is null.
FileNotFoundException - if archive cannot get opened for reading.
ZipException - if archive is not compatible to the ZIP File Format Specification.
IOException - on any other I/O related issue.

RawZipFile

RawZipFile(@NonNull
           Pool<ReadOnlyFile,IOException> source,
           @NonNull
           Charset charset,
           boolean preambled,
           boolean postambled,
           @NonNull
           ZipEntryFactory<E> factory)
     throws IOException
Throws:
IOException
Method Detail

mountCentralDirectory

private void mountCentralDirectory(ReadOnlyFile rof,
                                   boolean preambled,
                                   boolean postambled)
                            throws IOException
Reads the central directory of the given file and populates the internal tables with ZipEntry instances.

The ZipEntrys will know all data that can be obtained from the central directory alone, but not the data that requires the local file header or additional data to be read.

Throws:
ZipException - If the file is not compatible to the ZIP File Format Specification.
IOException - On any other I/O related issue.

decode

private String decode(byte[] bytes)

findCentralDirectory

private int findCentralDirectory(ReadOnlyFile rof,
                                 boolean preambled,
                                 boolean postambled)
                          throws ZipException,
                                 IOException
Positions the file pointer at the first Central File Header. Performs some means to check that this is really a ZIP file.

As a side effect, both mapper and }postamble} will be set.

Throws:
ZipException - If the file is not compatible to the ZIP File Format Specification.
IOException - On any other I/O related issue.

getComment

public String getComment()
Returns the comment of this ZIP file or null if no comment exists.


setComment

private void setComment(String comment)

busy

public boolean busy()
Returns true if and only if some input streams are busy with reading from this ZIP file.


getCharset

public String getCharset()
Returns the charset to use for entry names and the file comment.


size

public int size()
Returns the number of entries in this ZIP file.


iterator

public Iterator<E> iterator()
Returns an iteration of all entries in this ZIP file. Note that the iteration supports element removal and the returned entries are shared with this instance. It is illegal to change their state!

Specified by:
iterator in interface Iterable<E extends ZipEntry>

getEntry

public E getEntry(String name)
Returns the entry for the given name or null if no entry with this name exists. Note that the returned entry is shared with this instance. It is illegal to change its state!

Parameters:
name - the name of the ZIP entry.

length

public long length()
Returns the file length of this ZIP file in bytes.


getPreambleLength

public long getPreambleLength()
Returns the length of the preamble of this ZIP file in bytes.

Returns:
A positive value or zero to indicate that this ZIP file does not have a preamble.

getPreambleInputStream

public InputStream getPreambleInputStream()
                                   throws IOException
Returns an InputStream to read the preamble of this ZIP file.

Note that the returned stream is a lightweight stream, i.e. there is no external resource such as a ReadOnlyFile allocated for it. Instead, all streams returned by this method share the underlying ReadOnlyFile of this ZipFile. This allows to close this object (and hence the underlying ReadOnlyFile) without cooperation of the returned streams, which is important if the client application wants to work on the underlying file again (e.g. update or delete it).

Throws:
ZipException - If this ZIP file has been closed.
IOException

getPostambleLength

public long getPostambleLength()
Returns the length of the postamble of this ZIP file in bytes.

Returns:
A positive value or zero to indicate that this ZIP file does not have a postamble.

getPostambleInputStream

public InputStream getPostambleInputStream()
                                    throws IOException
Returns an InputStream to read the postamble of this ZIP file.

Note that the returned stream is a lightweight stream, i.e. there is no external resource such as a ReadOnlyFile allocated for it. Instead, all streams returned by this method share the underlying ReadOnlyFile of this ZipFile. This allows to close this object (and hence the underlying ReadOnlyFile) without cooperation of the returned streams, which is important if the client application wants to work on the underlying file again (e.g. update or delete it).

Throws:
ZipException - If this ZIP file has been closed.
IOException

getOffsetMapper

RawZipFile.OffsetMapper getOffsetMapper()

offsetsConsiderPreamble

public boolean offsetsConsiderPreamble()
Returns true if and only if the offsets in this ZIP file are relative to the start of the file, rather than the first Local File Header.

This method is intended for very special purposes only.


getInputStream

public final InputStream getInputStream(String name)
                                 throws IOException
Equivalent to getInputStream(name, false, true).

Throws:
IOException

getInputStream

public final InputStream getInputStream(ZipEntry entry)
                                 throws IOException
Equivalent to getInputStream(entry.getName(), false, true) instead.

Throws:
IOException

getCheckedInputStream

public final InputStream getCheckedInputStream(String name)
                                        throws IOException
Equivalent to getInputStream(name, true, true).

Throws:
IOException

getCheckedInputStream

public final InputStream getCheckedInputStream(ZipEntry entry)
                                        throws IOException
Equivalent to getInputStream(entry.getName(), true, true) instead.

Throws:
IOException

getInputStream

protected InputStream getInputStream(String name,
                                     boolean check,
                                     boolean inflate)
                              throws IOException
Returns an InputStream for reading the inflated or deflated data of the given entry.

If the close() method is called on this instance, all input streams returned by this method are closed, too.

Parameters:
name - The name of the entry to get the stream for - may not be null!
check - Whether or not the entry's CRC-32 value is checked. If and only if this parameter is true, two additional checks are performed for the ZIP entry:
  1. All entry headers are checked to have consistent declarations of the CRC-32 value for the inflated entry data.
  2. When calling InputStream.close() on the returned entry stream, the CRC-32 value computed from the inflated entry data is checked against the declared CRC-32 values. This is independent from the inflate parameter.
If any of these checks fail, a CRC32Exception is thrown.

This parameter should be false for most applications, and is the default for the sibling of this class in java.util.zip.ZipFile.

inflate - Whether or not the entry data should be inflated. If false, the entry data is not inflated, even if the entry data is deflated. This parameter should be true for most applications.
Returns:
A stream to read the entry data from or null if the entry does not exist.
Throws:
NullPointerException - If name is null.
CRC32Exception - If the declared CRC-32 values of the inflated entry data are inconsistent across the entry headers.
ZipException - If this file is not compatible to the ZIP File Format Specification.
IOException - If the entry cannot get read from this ZipFile.

getBufferSize

private static int getBufferSize(ZipEntry entry)

assertOpen

final void assertOpen()
               throws ZipException
Asserts that this ZIP file is still open for reading its entries.

Throws:
ZipException

skipWithBuffer

private static long skipWithBuffer(InputStream in,
                                   long toSkip,
                                   byte[] buf)
                            throws IOException
This method skips toSkip bytes in the given input stream using the given buffer unless EOF or IOException.

Throws:
IOException

close

public void close()
           throws IOException
Closes the file. This closes any fetch input streams reading from this ZIP file.

Specified by:
close in interface Closeable
Throws:
IOException - if an error occurs closing the file.

TrueZIP Driver ZIP 7.1

Copyright © 2005-2011 Schlichtherle IT Services. All Rights Reserved.