FileDocCategorySizeDatePackage
ZipEntry.javaAPI DocAndroid 1.5 API25193Wed May 06 22:41:02 BST 2009java.util.zip

ZipEntry

public class ZipEntry extends Object implements ZipConstants, Cloneable
An instance of {@code ZipEntry} represents an entry within a ZIP-archive. An entry has attributes such as name (= path) or the size of its data. While an entry identifies data stored in an archive, it does not hold the data itself. For example when reading a ZIP-file you will first retrieve all its entries in a collection and then read the data for a specific entry through an input stream.
see
ZipFile
see
ZipOutputStream
since
Android 1.0

Fields Summary
String
name
String
comment
long
compressedSize
long
crc
long
size
int
compressionMethod
int
time
int
modDate
byte[]
extra
private int
mVersionMadeBy
private int
mVersionToExtract
private int
mGPBitFlag
int
nameLen
int
extraLen
int
commentLen
private int
mDiskNumberStart
private int
mInternalAttrs
private long
mExternalAttrs
long
mLocalHeaderRelOffset
static final int
USES_DATA_DESCR
public static final int
DEFLATED
Zip entry state: Deflated.
public static final int
STORED
Zip entry state: Stored.
Constructors Summary
public ZipEntry(String name)
Constructs a new {@code ZipEntry} with the specified name.

param
name the name of the ZIP entry.
throws
IllegalArgumentException if the name length is outside the range (> 0xFFFF).
since
Android 1.0


                                                                 
       
        if (name == null) {
            throw new NullPointerException();
        }
        if (name.length() > 0xFFFF) {
            throw new IllegalArgumentException();
        }
        this.name = name;

        // BEGIN android-added
        mVersionMadeBy = 0x0317;        // 03=UNIX, 17=spec v2.3
        mVersionToExtract = 20;         // need deflate, not much else
        mGPBitFlag = 0;
        compressionMethod = -1;
        time = -1;
        modDate = -1;
        crc = -1L;
        compressedSize = -1L;
        size = -1L;
        extraLen = -1;
        nameLen = -1;
        mDiskNumberStart = 0;
        mInternalAttrs = 0;
        mExternalAttrs = 0x81b60020L;       // matches WinZip
        mLocalHeaderRelOffset = -1;
        extra = null;
        comment = null;
        // END android-added
    
public ZipEntry(ZipEntry ze)
Constructs a new {@code ZipEntry} using the values obtained from {@code ze}.

param
ze the {@code ZipEntry} from which to obtain values.
since
Android 1.0

        name = ze.name;
        comment = ze.comment;
        time = ze.time;
        size = ze.size;
        compressedSize = ze.compressedSize;
        crc = ze.crc;
        compressionMethod = ze.compressionMethod;
        modDate = ze.modDate;
        extra = ze.extra;
        // BEGIN android-removed
        // dataOffset = ze.dataOffset;
        // END android-removed
        // BEGIN android-added
        mVersionMadeBy = ze.mVersionMadeBy;
        mVersionToExtract = ze.mVersionToExtract;
        mGPBitFlag = ze.mGPBitFlag;
        extraLen = ze.extraLen;
        nameLen = ze.nameLen;
        mDiskNumberStart = ze.mDiskNumberStart;
        mInternalAttrs = ze.mInternalAttrs;
        mExternalAttrs = ze.mExternalAttrs;
        mLocalHeaderRelOffset = ze.mLocalHeaderRelOffset;
        // END android-added
    
ZipEntry(LittleEndianReader ler, InputStream in)


        /*
         * We're seeing performance issues when we call readShortLE and
         * readIntLE, so we're going to read the entire header at once
         * and then parse the results out without using any function calls.
         * Uglier, but should be much faster.
         * 
         * Note that some lines look a bit different, because the corresponding
         * fields or locals are long and so we need to do & 0xffffffffl to avoid
         * problems induced by sign extension.
         */

        byte[] hdrBuf = ler.hdrBuf;
        myReadFully(in, hdrBuf);

        long sig = (hdrBuf[0] & 0xff) | ((hdrBuf[1] & 0xff) << 8) |
            ((hdrBuf[2] & 0xff) << 16) | ((hdrBuf[3] << 24) & 0xffffffffL);
        if (sig != CENSIG)
             throw new ZipException("Central Directory Entry not found");

        mVersionMadeBy = (hdrBuf[4] & 0xff) | ((hdrBuf[5] & 0xff) << 8);
        mVersionToExtract = (hdrBuf[6] & 0xff) | ((hdrBuf[7] & 0xff) << 8);
        mGPBitFlag = (hdrBuf[8] & 0xff) | ((hdrBuf[9] & 0xff) << 8);
        compressionMethod = (hdrBuf[10] & 0xff) | ((hdrBuf[11] & 0xff) << 8);
        time = (hdrBuf[12] & 0xff) | ((hdrBuf[13] & 0xff) << 8);
        modDate = (hdrBuf[14] & 0xff) | ((hdrBuf[15] & 0xff) << 8);
        crc = (hdrBuf[16] & 0xff) | ((hdrBuf[17] & 0xff) << 8)
                | ((hdrBuf[18] & 0xff) << 16)
                | ((hdrBuf[19] << 24) & 0xffffffffL);
        compressedSize = (hdrBuf[20] & 0xff) | ((hdrBuf[21] & 0xff) << 8)
                | ((hdrBuf[22] & 0xff) << 16)
                | ((hdrBuf[23] << 24) & 0xffffffffL);
        size = (hdrBuf[24] & 0xff) | ((hdrBuf[25] & 0xff) << 8)
                | ((hdrBuf[26] & 0xff) << 16)
                | ((hdrBuf[27] << 24) & 0xffffffffL);
        nameLen = (hdrBuf[28] & 0xff) | ((hdrBuf[29] & 0xff) << 8);
        extraLen = (hdrBuf[30] & 0xff) | ((hdrBuf[31] & 0xff) << 8);
        commentLen = (hdrBuf[32] & 0xff) | ((hdrBuf[33] & 0xff) << 8);
        mDiskNumberStart = (hdrBuf[34] & 0xff) | ((hdrBuf[35] & 0xff) << 8);
        mInternalAttrs = (hdrBuf[36] & 0xff) | ((hdrBuf[37] & 0xff) << 8);
        mExternalAttrs = (hdrBuf[38] & 0xff) | ((hdrBuf[39] & 0xff) << 8)
                | ((hdrBuf[40] & 0xff) << 16)
                | ((hdrBuf[41] << 24) & 0xffffffffL);
        mLocalHeaderRelOffset = (hdrBuf[42] & 0xff) | ((hdrBuf[43] & 0xff) << 8)
                | ((hdrBuf[44] & 0xff) << 16)
                | ((hdrBuf[45] << 24) & 0xffffffffL);

        byte[] nameBytes = new byte[nameLen];
        myReadFully(in, nameBytes);

        byte[] commentBytes = null;
        if (commentLen > 0) {
            commentBytes = new byte[commentLen];
            myReadFully(in, commentBytes);
        }

        if (extraLen > 0) {
            extra = new byte[extraLen];
            myReadFully(in, extra);
        }

        try {
            /*
             * The actual character set is "IBM Code Page 437".  As of
             * Sep 2006, the Zip spec (APPNOTE.TXT) supports UTF-8.  When
             * bit 11 of the GP flags field is set, the file name and
             * comment fields are UTF-8.
             *
             * TODO: add correct UTF-8 support.
             */
            name = new String(nameBytes, "ISO-8859-1");
            if (commentBytes != null)
                comment = new String(commentBytes, "ISO-8859-1");
            else
                comment = null;
        }
        catch (UnsupportedEncodingException uee) {
            throw new InternalError(uee.getMessage());
        }
    
Methods Summary
public java.lang.Objectclone()
Returns a shallow copy of this entry.

return
a copy of this entry.
since
Android 1.0

        return new ZipEntry(this);
    
public java.lang.StringgetComment()
Gets the comment for this {@code ZipEntry}.

return
the comment for this {@code ZipEntry}, or {@code null} if there is no comment. If we're reading an archive with {@code ZipInputStream} the comment is not available.
since
Android 1.0

        return comment;
    
public longgetCompressedSize()
Gets the compressed size of this {@code ZipEntry}.

return
the compressed size, or -1 if the compressed size has not been set.
since
Android 1.0

        return compressedSize;
    
public longgetCrc()
Gets the checksum for this {@code ZipEntry}.

return
the checksum, or -1 if the checksum has not been set.
since
Android 1.0

        return crc;
    
public byte[]getExtra()
Gets the extra information for this {@code ZipEntry}.

return
a byte array containing the extra information, or {@code null} if there is none.
since
Android 1.0

        return extra;
    
intgetGPBitFlag()

        return mGPBitFlag;
    
longgetLocalHeaderRelOffset()

        return mLocalHeaderRelOffset;
    
public intgetMethod()
Gets the compression method for this {@code ZipEntry}.

return
the compression method, either {@code DEFLATED}, {@code STORED} or -1 if the compression method has not been set.
since
Android 1.0

        return compressionMethod;
    
public java.lang.StringgetName()
Gets the name of this {@code ZipEntry}.

return
the entry name.
since
Android 1.0

        return name;
    
public longgetSize()
Gets the uncompressed size of this {@code ZipEntry}.

return
the uncompressed size, or {@code -1} if the size has not been set.
since
Android 1.0

        return size;
    
public longgetTime()
Gets the last modification time of this {@code ZipEntry}.

return
the last modification time as the number of milliseconds since Jan. 1, 1970.
since
Android 1.0

        if (time != -1) {
            GregorianCalendar cal = new GregorianCalendar();
            cal.set(Calendar.MILLISECOND, 0);
            cal.set(1980 + ((modDate >> 9) & 0x7f), ((modDate >> 5) & 0xf) - 1,
                    modDate & 0x1f, (time >> 11) & 0x1f, (time >> 5) & 0x3f,
                    (time & 0x1f) << 1);
            return cal.getTime().getTime();
        }
        return -1;
    
public inthashCode()
Returns the hash code for this {@code ZipEntry}.

return
the hash code of the entry.
since
Android 1.0

        return name.hashCode();
    
public booleanisDirectory()
Determine whether or not this {@code ZipEntry} is a directory.

return
{@code true} when this {@code ZipEntry} is a directory, {@code false} otherwise.
since
Android 1.0

        return name.charAt(name.length() - 1) == '/";
    
private voidmyReadFully(java.io.InputStream in, byte[] b)

        int count;
        int len = b.length;
        int off = 0;
    
        while (len > 0) {
            count = in.read(b, off, len);
            if (count <= 0)
                throw new EOFException();
            off += count;
            len -= count;
        }
    
static longreadIntLE(java.io.RandomAccessFile raf)

        int b0, b1, b2, b3;

        b0 = raf.read();
        b1 = raf.read();
        b2 = raf.read();
        b3 = raf.read();
        if (b3 < 0)
            throw new EOFException("in ZipEntry.readIntLE(RandomAccessFile)");
        return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); // ATTENTION: DOES SIGN EXTENSION: IS THIS WANTED?
    
static intreadShortLE(java.io.RandomAccessFile raf)

        int b0, b1;

        b0 = raf.read();
        b1 = raf.read();
        if (b1 < 0)
            throw new EOFException("in ZipEntry.readShortLE(RandomAccessFile)");
        return b0 | (b1 << 8);
    
public voidsetComment(java.lang.String string)
Sets the comment for this {@code ZipEntry}.

param
string the comment for this entry.
since
Android 1.0

        if (string == null || string.length() <= 0xFFFF) {
            comment = string;
        } else {
            throw new IllegalArgumentException();
        }
    
public voidsetCompressedSize(long value)
Sets the compressed size for this {@code ZipEntry}.

param
value the compressed size (in bytes).
since
Android 1.0

        compressedSize = value;
    
public voidsetCrc(long value)
Sets the checksum for this {@code ZipEntry}.

param
value the checksum for this entry.
throws
IllegalArgumentException if {@code value} is < 0 or > 0xFFFFFFFFL.
since
Android 1.0

        if (value >= 0 && value <= 0xFFFFFFFFL) {
            crc = value;
        } else {
            throw new IllegalArgumentException();
        }
    
voidsetDateTime(int lastModFileDate, int lastModFileTime)

        time = lastModFileTime;
        modDate = lastModFileDate;
    
public voidsetExtra(byte[] data)
Sets the extra information for this {@code ZipEntry}.

param
data a byte array containing the extra information.
throws
IllegalArgumentException when the length of data is greater than 0xFFFF bytes.
since
Android 1.0

        if (data == null || data.length <= 0xFFFF) {
            extra = data;
        } else {
            throw new IllegalArgumentException();
        }
    
voidsetGPBitFlag(int flags)

        mGPBitFlag = flags;
    
voidsetLocalHeaderRelOffset(long offset)

        mLocalHeaderRelOffset = offset;
    
public voidsetMethod(int value)
Sets the compression method for this {@code ZipEntry}.

param
value the compression method, either {@code DEFLATED} or {@code STORED}.
throws
IllegalArgumentException when value is not {@code DEFLATED} or {@code STORED}.
since
Android 1.0

        if (value != STORED && value != DEFLATED) {
            throw new IllegalArgumentException();
        }
        compressionMethod = value;
    
public voidsetSize(long value)
Sets the uncompressed size of this {@code ZipEntry}.

param
value the uncompressed size for this entry.
throws
IllegalArgumentException if {@code value} < 0 or {@code value} > 0xFFFFFFFFL.
since
Android 1.0

        if (value >= 0 && value <= 0xFFFFFFFFL) {
            size = value;
        } else {
            throw new IllegalArgumentException();
        }
    
public voidsetTime(long value)
Sets the modification time of this {@code ZipEntry}.

param
value the modification time as the number of milliseconds since Jan. 1, 1970.
since
Android 1.0

        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(new Date(value));
        int year = cal.get(Calendar.YEAR);
        if (year < 1980) {
            modDate = 0x21;
            time = 0;
        } else {
            modDate = cal.get(Calendar.DATE);
            modDate = (cal.get(Calendar.MONTH) + 1 << 5) | modDate;
            modDate = ((cal.get(Calendar.YEAR) - 1980) << 9) | modDate;
            time = cal.get(Calendar.SECOND) >> 1;
            time = (cal.get(Calendar.MINUTE) << 5) | time;
            time = (cal.get(Calendar.HOUR_OF_DAY) << 11) | time;
        }
    
voidsetVersionToExtract(int version)

        mVersionToExtract = version;
    
public java.lang.StringtoString()
Returns the string representation of this {@code ZipEntry}.

return
the string representation of this {@code ZipEntry}.
since
Android 1.0

        return name;
    
intwriteCDE(java.io.OutputStream out)

        writeIntLE(out, CENSIG);
        writeShortLE(out, mVersionMadeBy);
        writeShortLE(out, mVersionToExtract);
        writeShortLE(out, mGPBitFlag);
        writeShortLE(out, compressionMethod);
        writeShortLE(out, time);
        writeShortLE(out, modDate);
        writeIntLE(out, crc);
        writeIntLE(out, compressedSize);
        writeIntLE(out, size);

        byte[] nameBytes = null, commentBytes = null;
        try {
            nameBytes = name.getBytes("ISO-8859-1");
            if (comment != null)
                commentBytes = comment.getBytes("ISO-8859-1");
        }
        catch (UnsupportedEncodingException uee) {
            throw new InternalError(uee.getMessage());
        }

        int extraLen = 0, commentLen = 0;
        if (extra != null)
            extraLen = extra.length;
        if (commentBytes != null)
            commentLen = commentBytes.length;

        writeShortLE(out, nameBytes.length);
        writeShortLE(out, extraLen);
        writeShortLE(out, commentLen);
        writeShortLE(out, mDiskNumberStart);
        writeShortLE(out, mInternalAttrs);
        writeIntLE(out, mExternalAttrs);
        writeIntLE(out, mLocalHeaderRelOffset);
        out.write(nameBytes);
        if (extra != null)
            out.write(extra);
        if (commentBytes != null)
            out.write(commentBytes);

        return CENHDR + nameBytes.length + extraLen + commentLen;
    
intwriteDD(java.io.OutputStream out)

        writeIntLE(out, EXTSIG);
        writeIntLE(out, crc);
        writeIntLE(out, compressedSize);
        writeIntLE(out, size);
        return EXTHDR;
    
static voidwriteIntLE(java.io.OutputStream out, long val)

        if (val < 0)
            throw new InternalError();
        out.write((int) val & 0xff);
        out.write(((int) val >> 8) & 0xff);
        out.write(((int) val >> 16) & 0xff);
        out.write(((int) val >> 24) & 0xff);
    
intwriteLFH(java.io.OutputStream out)

        if (compressionMethod < 0 ||
            time < 0 ||
            modDate < 0 ||
            crc < 0 ||
            compressedSize < 0 ||
            size < 0)
            throw new InternalError();

        writeIntLE(out, LOCSIG);
        writeShortLE(out, mVersionToExtract);
        writeShortLE(out, mGPBitFlag);
        writeShortLE(out, compressionMethod);
        writeShortLE(out, time);
        writeShortLE(out, modDate);
        writeIntLE(out, crc);
        writeIntLE(out, compressedSize);
        writeIntLE(out, size);

        byte[] nameBytes;
        try {
            nameBytes = name.getBytes("ISO-8859-1");
        }
        catch (UnsupportedEncodingException uee) {
            throw new InternalError(uee.getMessage());
        }

        int extraLen = 0;
        if (extra != null)
            extraLen = extra.length;

        writeShortLE(out, nameBytes.length);
        writeShortLE(out, extraLen);
        out.write(nameBytes);
        if (extra != null)
            out.write(extra);

        return LOCHDR + nameBytes.length + extraLen;
    
static voidwriteShortLE(java.io.OutputStream out, int val)

        out.write(val & 0xff);
        out.write((val >> 8) & 0xff);