FileDocCategorySizeDatePackage
ZipFile.javaAPI DocJava SE 5 API22596Fri Aug 26 14:57:28 BST 2005java.util.zip

ZipFile

public class ZipFile extends Object implements ZipConstants
This class is used to read entries from a zip file.

Unless otherwise noted, passing a null argument to a constructor or method in this class will cause a {@link NullPointerException} to be thrown.

version
1.70, 04/25/05
author
David Connelly

Fields Summary
private long
jzfile
private String
name
private int
total
private MappedByteBuffer
mappedBuffer
private ZipCloser
closer
private boolean
mbUsed
private boolean
closeRequested
private static final int
STORED
private static final int
DEFLATED
public static final int
OPEN_READ
Mode flag to open a zip file for reading.
public static final int
OPEN_DELETE
Mode flag to open a zip file and mark it for deletion. The file will be deleted some time between the moment that it is opened and the moment that it is closed, but its contents will remain accessible via the ZipFile object until either the close method is invoked or the virtual machine exits.
private static Constructor
directByteBufferConstructor
private Vector
inflaters
Constructors Summary
public ZipFile(File file)
Opens a ZIP file for reading given the specified File object.

param
file the ZIP file to be opened for reading
throws
ZipException if a ZIP error has occurred
throws
IOException if an I/O error has occurred

	this(file, OPEN_READ);
    
public ZipFile(String name)
Opens a zip file for reading.

First, if there is a security manager, its checkRead method is called with the name argument as its argument to ensure the read is allowed.

param
name the name of the zip file
throws
ZipException if a ZIP format error has occurred
throws
IOException if an I/O error has occurred
throws
SecurityException if a security manager exists and its checkRead method doesn't allow read access to the file.
see
SecurityManager#checkRead(java.lang.String)

    
     
	/* Zip library is loaded from System.initializeSystemClass */
	initIDs();
    
	this(new File(name), OPEN_READ);
    
public ZipFile(File file, int mode)
Opens a new ZipFile to read from the specified File object in the specified mode. The mode argument must be either OPEN_READ or OPEN_READ | OPEN_DELETE.

First, if there is a security manager, its checkRead method is called with the name argument as its argument to ensure the read is allowed.

param
file the ZIP file to be opened for reading
param
mode the mode in which the file is to be opened
throws
ZipException if a ZIP format error has occurred
throws
IOException if an I/O error has occurred
throws
SecurityException if a security manager exists and its checkRead method doesn't allow read access to the file, or its checkDelete method doesn't allow deleting the file when the OPEN_DELETE flag is set.
throws
IllegalArgumentException if the mode argument is invalid
see
SecurityManager#checkRead(java.lang.String)

        if (((mode & OPEN_READ) == 0) || 
            ((mode & ~(OPEN_READ | OPEN_DELETE)) != 0)) {
            throw new IllegalArgumentException("Illegal mode: 0x"+ 
                                               Integer.toHexString(mode));
        }
        String name = file.getPath();
	SecurityManager sm = System.getSecurityManager();
	if (sm != null) {
	    sm.checkRead(name);
	    if ((mode & OPEN_DELETE) != 0) {
		sm.checkDelete(name);
	    }
	}
	long jzfileCopy = open(name, mode, file.lastModified());
	this.name = name;
	this.total = getTotal(jzfileCopy);
	this.mbUsed = false;
	long mappedAddr = getMappedAddr(jzfileCopy);
	long len = getMappedLen(jzfileCopy);

	if (mappedAddr != 0 && len < Integer.MAX_VALUE) {
	    // Zip's native code may be able to handle files up to 4GB, but
	    // ByteBuffers can only handle 2GB. So fallback on Zip files >= 2GB.
	    this.closer = new ZipCloser(jzfileCopy); 
	    this.mappedBuffer = newMappedByteBuffer((int)len, mappedAddr, 
						    this.closer);
	}

        jzfile = jzfileCopy;
    
Methods Summary
public voidclose()
Closes the ZIP file.

Closing this ZIP file will close all of the input streams previously returned by invocations of the {@link #getInputStream getInputStream} method.

throws
IOException if an I/O error has occurred

        synchronized (this) {
	    closeRequested = true;
	    
	    if (jzfile != 0) {
		// Close the zip file
		long zf = this.jzfile;
		jzfile = 0;
		if (closer != null) {
		    if (!mbUsed) { // no one is looking; we can close early
			closer.setClosed(); // tell closer not to bother
			close(zf);
		    }
		    // Some caller may have ref to MappedByteBuffer,
		    // so let phantom processing (ZipCloser) close the ZipFile.
		} else {
		    close(zf);
		}
		// Release inflaters
		synchronized (inflaters) {
		    int size = inflaters.size();
		    for (int i = 0; i < size; i++) {
			Inflater inf = (Inflater)inflaters.get(i);
			inf.end();
		    }
		}
	    }
        }
    
private static native voidclose(long jzfile)

private voidensureOpen()

	if (closeRequested) {
	    throw new IllegalStateException("zip file closed");
	}
    
private voidensureOpenOrZipException()

	if (closeRequested) {
	    throw new ZipException("ZipFile closed");
	}
    
public java.util.Enumerationentries()
Returns an enumeration of the ZIP file entries.

return
an enumeration of the ZIP file entries
throws
IllegalStateException if the zip file has been closed

        ensureOpen();
        return new Enumeration<ZipEntry>() {
                private int i = 0;
                public boolean hasMoreElements() {
                    synchronized (ZipFile.this) {
                        ensureOpen();
                        return i < total;
                    }
                }
                public ZipEntry nextElement() throws NoSuchElementException {
                    synchronized (ZipFile.this) {
                        ensureOpen();
                        if (i >= total) {
                            throw new NoSuchElementException();
                        }
                        long jzentry = getNextEntry(jzfile, i++);
                        if (jzentry == 0) {
                            String message;
                            if (closeRequested) {
                                message = "ZipFile concurrently closed";
                            } else {
                                message = getZipMessage(ZipFile.this.jzfile);
                            }
                            throw new InternalError("jzentry == 0" +
                                                    ",\n jzfile = " + ZipFile.this.jzfile +
                                                    ",\n total = " + ZipFile.this.total +
                                                    ",\n name = " + ZipFile.this.name +
                                                    ",\n i = " + i +
                                                    ",\n message = " + message
                                );
                        }
                        ZipEntry ze = new ZipEntry(jzentry);
                        freeEntry(jzfile, jzentry);
                        return ze;
                    }
                }
            };
    
protected voidfinalize()
Ensures that the close method of this ZIP file is called when there are no more references to it.

Since the time when GC would invoke this method is undetermined, it is strongly recommended that applications invoke the close method as soon they have finished accessing this ZipFile. This will prevent holding up system resources for an undetermined length of time.

throws
IOException if an I/O error has occurred
see
java.util.zip.ZipFile#close()

        close();
    
private static native voidfreeEntry(long jzfile, long jzentry)

private static native longgetCSize(long jzentry)

public java.util.zip.ZipEntrygetEntry(java.lang.String name)
Returns the zip file entry for the specified name, or null if not found.

param
name the name of the entry
return
the zip file entry, or null if not found
throws
IllegalStateException if the zip file has been closed

        if (name == null) {
            throw new NullPointerException("name");
        }
        long jzentry = 0;
        synchronized (this) {
            ensureOpen();
            jzentry = getEntry(jzfile, name, true);
            if (jzentry != 0) {
                ZipEntry ze = new ZipEntry(name, jzentry);
                freeEntry(jzfile, jzentry);
                return ze;
            }
        }
        return null;
    
private static native longgetEntry(long jzfile, java.lang.String name, boolean addSlash)

private static native longgetEntryOffset(long jzentry)

private java.util.zip.InflatergetInflater()

	synchronized (inflaters) {
	    int size = inflaters.size();
	    if (size > 0) {
		Inflater inf = (Inflater)inflaters.remove(size - 1);
		inf.reset();
		return inf;
	    } else {
		return new Inflater(true);
	    }
	}
    
public java.io.InputStreamgetInputStream(java.util.zip.ZipEntry entry)
Returns an input stream for reading the contents of the specified zip file entry. Returns an input stream for reading the contents of the specified zip file entry.

Closing this ZIP file will, in turn, close all input streams that have been returned by invocations of this method.

param
entry the zip file entry
return
the input stream for reading the contents of the specified zip file entry.
throws
ZipException if a ZIP format error has occurred
throws
IOException if an I/O error has occurred
throws
IllegalStateException if the zip file has been closed

	return getInputStream(entry.name);
    
private java.io.InputStreamgetInputStream(java.lang.String name)
Returns an input stream for reading the contents of the specified entry, or null if the entry was not found.

	if (name == null) {
	    throw new NullPointerException("name");
	}
        long jzentry = 0;
        ZipFileInputStream in = null;
        synchronized (this) {
            ensureOpen();
            jzentry = getEntry(jzfile, name, false);
            if (jzentry == 0) {
                return null;
            }
	    if (mappedBuffer != null) {
		in = new MappedZipFileInputStream(jzentry, name);
	    } else {
		in = new ZipFileInputStream(jzentry);
	    }
        }
        final ZipFileInputStream zfin = in;
	switch (getMethod(jzentry)) {
	case STORED:
	    return zfin;
	case DEFLATED:
	    // MORE: Compute good size for inflater stream:
            long size = getSize(jzentry);
            if (size > 65536) size = 8192;
            if (size <= 0) size = 4096;
            return new InflaterInputStream(zfin, getInflater(), (int)size) {
                private boolean isClosed = false;
                
		public void close() throws IOException {
                    if (!isClosed) {
                         releaseInflater(inf);
                        this.in.close();
                        isClosed = true;
                    }
		}
		// Override fill() method to provide an extra "dummy" byte
		// at the end of the input stream. This is required when
		// using the "nowrap" Inflater option.
		protected void fill() throws IOException {
		    if (eof) {
			throw new EOFException(
			    "Unexpected end of ZLIB input stream");
		    }
		    len = this.in.read(buf, 0, buf.length);
		    if (len == -1) {
			buf[0] = 0;
			len = 1;
			eof = true;
		    }
		    inf.setInput(buf, 0, len);
		}
		private boolean eof;

                public int available() throws IOException {
                    if (isClosed)
                        return 0;
		    long avail = zfin.size() - inf.getBytesWritten();
		    return avail > (long) Integer.MAX_VALUE ?
			Integer.MAX_VALUE : (int) avail;
                }
	    };
	default:
	    throw new ZipException("invalid compression method");
	}
    
private static native longgetMappedAddr(long jzfile)

private static native longgetMappedLen(long jzfile)

private static native intgetMethod(long jzentry)

public java.lang.StringgetName()
Returns the path name of the ZIP file.

return
the path name of the ZIP file


                         
       
        return name;
    
private static native longgetNextEntry(long jzfile, int i)

private static native longgetSize(long jzentry)

private static native intgetTotal(long jzfile)

private static native java.lang.StringgetZipMessage(long jzfile)

private static voidinitDBBConstructor()


        
	AccessController.doPrivileged(new PrivilegedAction() {
		public Object run() {
		    try {
			Class th = Class.forName("java.nio.DirectByteBuffer");
			directByteBufferConstructor
			    = th.getDeclaredConstructor(
					new Class[] { int.class,
                                                      long.class,
						      Runnable.class });
			directByteBufferConstructor.setAccessible(true);
		    } catch (ClassNotFoundException x) {
			throw new InternalError();
		    } catch (NoSuchMethodException x) {
			throw new InternalError();
		    } catch (IllegalArgumentException x) {
			throw new InternalError();
		    } catch (ClassCastException x) {
			throw new InternalError();
		    }
                    return null;
		}});
    
private static native voidinitIDs()

private static java.nio.MappedByteBuffernewMappedByteBuffer(int size, long addr, java.lang.Runnable unmapper)

        MappedByteBuffer dbb;
        if (directByteBufferConstructor == null)
            initDBBConstructor();
        try {
            dbb = (MappedByteBuffer)directByteBufferConstructor.newInstance(
              new Object[] { new Integer(size),
                             new Long(addr),
			     unmapper });
        } catch (InstantiationException e) {
            throw new InternalError();
        } catch (IllegalAccessException e) {
            throw new InternalError();
        } catch (InvocationTargetException e) {
            throw new InternalError();
        }
        return dbb;
    
private static native longopen(java.lang.String name, int mode, long lastModified)

private static native intread(long jzfile, long jzentry, long pos, byte[] b, int off, int len)

private voidreleaseInflater(java.util.zip.Inflater inf)

	synchronized (inflaters) {
	    inflaters.add(inf);
	}
    
public intsize()
Returns the number of entries in the ZIP file.

return
the number of entries in the ZIP file
throws
IllegalStateException if the zip file has been closed

        ensureOpen();
	return total;