zipfile.java
来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 673 行 · 第 1/2 页
JAVA
673 行
catch (IOException ioe) { return EmptyEnumeration.getInstance(); } } /** * Checks that the ZipFile is still open and reads entries when necessary. * * @exception IllegalStateException when the ZipFile has already been closed. * @exception IOException when the entries could not be read. */ private HashMap getEntries() throws IOException { synchronized(raf) { checkClosed(); if (entries == null) readEntries(); return entries; } } /** * Searches for a zip entry in this archive with the given name. * * @param name the name. May contain directory components separated by * slashes ('/'). * @return the zip entry, or null if no entry with that name exists. * * @exception IllegalStateException when the ZipFile has already been closed */ public ZipEntry getEntry(String name) { checkClosed(); try { HashMap entries = getEntries(); ZipEntry entry = (ZipEntry) entries.get(name); // If we didn't find it, maybe it's a directory. if (entry == null && !name.endsWith("/")) entry = (ZipEntry) entries.get(name + '/'); return entry != null ? new ZipEntry(entry, name) : null; } catch (IOException ioe) { return null; } } /** * Creates an input stream reading the given zip entry as * uncompressed data. Normally zip entry should be an entry * returned by getEntry() or entries(). * * This implementation returns null if the requested entry does not * exist. This decision is not obviously correct, however, it does * appear to mirror Sun's implementation, and it is consistant with * their javadoc. On the other hand, the old JCL book, 2nd Edition, * claims that this should return a "non-null ZIP entry". We have * chosen for now ignore the old book, as modern versions of Ant (an * important application) depend on this behaviour. See discussion * in this thread: * http://gcc.gnu.org/ml/java-patches/2004-q2/msg00602.html * * @param entry the entry to create an InputStream for. * @return the input stream, or null if the requested entry does not exist. * * @exception IllegalStateException when the ZipFile has already been closed * @exception IOException if a i/o error occured. * @exception ZipException if the Zip archive is malformed. */ public InputStream getInputStream(ZipEntry entry) throws IOException { checkClosed(); HashMap entries = getEntries(); String name = entry.getName(); ZipEntry zipEntry = (ZipEntry) entries.get(name); if (zipEntry == null) return null; PartialInputStream inp = new PartialInputStream(raf, 1024); inp.seek(zipEntry.offset); if (inp.readLeInt() != LOCSIG) throw new ZipException("Wrong Local header signature: " + name); inp.skip(4); if (zipEntry.getMethod() != inp.readLeShort()) throw new ZipException("Compression method mismatch: " + name); inp.skip(16); int nameLen = inp.readLeShort(); int extraLen = inp.readLeShort(); inp.skip(nameLen + extraLen); inp.setLength(zipEntry.getCompressedSize()); int method = zipEntry.getMethod(); switch (method) { case ZipOutputStream.STORED: return inp; case ZipOutputStream.DEFLATED: return new InflaterInputStream(inp, new Inflater(true)); default: throw new ZipException("Unknown compression method " + method); } } /** * Returns the (path) name of this zip file. */ public String getName() { return name; } /** * Returns the number of entries in this zip file. * * @exception IllegalStateException when the ZipFile has already been closed */ public int size() { checkClosed(); try { return getEntries().size(); } catch (IOException ioe) { return 0; } } private static class ZipEntryEnumeration implements Enumeration { private final Iterator elements; public ZipEntryEnumeration(Iterator elements) { this.elements = elements; } public boolean hasMoreElements() { return elements.hasNext(); } public Object nextElement() { /* We return a clone, just to be safe that the user doesn't * change the entry. */ return ((ZipEntry)elements.next()).clone(); } } private static final class PartialInputStream extends InputStream { private final RandomAccessFile raf; private final byte[] buffer; private long bufferOffset; private int pos; private long end; public PartialInputStream(RandomAccessFile raf, int bufferSize) throws IOException { this.raf = raf; buffer = new byte[bufferSize]; bufferOffset = -buffer.length; pos = buffer.length; end = raf.length(); } void setLength(long length) { end = bufferOffset + pos + length; } private void fillBuffer() throws IOException { synchronized (raf) { raf.seek(bufferOffset); raf.readFully(buffer, 0, (int) Math.min(buffer.length, end - bufferOffset)); } } public int available() { long amount = end - (bufferOffset + pos); if (amount > Integer.MAX_VALUE) return Integer.MAX_VALUE; return (int) amount; } public int read() throws IOException { if (bufferOffset + pos >= end) return -1; if (pos == buffer.length) { bufferOffset += buffer.length; pos = 0; fillBuffer(); } return buffer[pos++] & 0xFF; } public int read(byte[] b, int off, int len) throws IOException { if (len > end - (bufferOffset + pos)) { len = (int) (end - (bufferOffset + pos)); if (len == 0) return -1; } int totalBytesRead = Math.min(buffer.length - pos, len); System.arraycopy(buffer, pos, b, off, totalBytesRead); pos += totalBytesRead; off += totalBytesRead; len -= totalBytesRead; while (len > 0) { bufferOffset += buffer.length; pos = 0; fillBuffer(); int remain = Math.min(buffer.length, len); System.arraycopy(buffer, pos, b, off, remain); pos += remain; off += remain; len -= remain; totalBytesRead += remain; } return totalBytesRead; } public long skip(long amount) throws IOException { if (amount < 0) return 0; if (amount > end - (bufferOffset + pos)) amount = end - (bufferOffset + pos); seek(bufferOffset + pos + amount); return amount; } void seek(long newpos) throws IOException { long offset = newpos - bufferOffset; if (offset >= 0 && offset <= buffer.length) { pos = (int) offset; } else { bufferOffset = newpos; pos = 0; fillBuffer(); } } void readFully(byte[] buf) throws IOException { if (read(buf, 0, buf.length) != buf.length) throw new EOFException(); } void readFully(byte[] buf, int off, int len) throws IOException { if (read(buf, off, len) != len) throw new EOFException(); } int readLeShort() throws IOException { int b0 = read(); int b1 = read(); if (b1 == -1) throw new EOFException(); return (b0 & 0xff) | (b1 & 0xff) << 8; } int readLeInt() throws IOException { int b0 = read(); int b1 = read(); int b2 = read(); int b3 = read(); if (b3 == -1) throw new EOFException(); return ((b0 & 0xff) | (b1 & 0xff) << 8) | ((b2 & 0xff) | (b3 & 0xff) << 8) << 16; } String readString(int length) throws IOException { if (length > end - (bufferOffset + pos)) throw new EOFException(); try { if (buffer.length - pos >= length) { String s = new String(buffer, pos, length, "UTF-8"); pos += length; return s; } else { byte[] b = new byte[length]; readFully(b); return new String(b, 0, length, "UTF-8"); } } catch (UnsupportedEncodingException uee) { throw new AssertionError(uee); } } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?