zipfile.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 661 行 · 第 1/2 页
JAVA
661 行
* @param the name. May contain directory components separated by
* slashes ('/').
* @return the zip entry, or null if no entry with that name exists.
*/
public ZipEntry getEntry(String name) {
try {
HashMap entries = getEntries();
ZipEntry entry = (ZipEntry) entries.get(name);
return entry != null ? (ZipEntry) entry.clone() : null;
} catch (IOException ioe) {
return null;
}
}
//access should be protected by synchronized(raf)
private byte[] locBuf = new byte[LOCHDR];
/**
* Checks, if the local header of the entry at index i matches the
* central directory, and returns the offset to the data.
*
* @param entry to check.
* @return the start offset of the (compressed) data.
*
* @exception IOException if a i/o error occured.
* @exception ZipException if the local header doesn't match the
* central directory header
*/
private long checkLocalHeader(ZipEntry entry) throws IOException {
synchronized (raf) {
raf.seek(entry.offset);
raf.readFully(locBuf);
if (readLeInt(locBuf, 0) != LOCSIG)
throw new ZipException("Wrong Local header signature: " + name);
if (entry.getMethod() != readLeShort(locBuf, LOCHOW))
throw new ZipException("Compression method mismatch: " + name);
if (entry.getName().length() != readLeShort(locBuf, LOCNAM))
throw new ZipException("file name length mismatch: " + name);
int extraLen = entry.getName().length() + readLeShort(locBuf, LOCEXT);
return entry.offset + LOCHDR + extraLen;
}
}
/**
* Creates an input stream reading the given zip entry as
* uncompressed data. Normally zip entry should be an entry
* returned by getEntry() or entries().
*
* @param entry the entry to create an InputStream for.
* @return the input stream.
*
* @exception IOException if a i/o error occured.
* @exception ZipException if the Zip archive is malformed.
*/
public InputStream getInputStream(ZipEntry entry) throws IOException {
HashMap entries = getEntries();
String name = entry.getName();
ZipEntry zipEntry = (ZipEntry) entries.get(name);
if (zipEntry == null)
throw new NoSuchElementException(name);
long start = checkLocalHeader(zipEntry);
int method = zipEntry.getMethod();
InputStream is = new BufferedInputStream(new PartialInputStream(raf, start, zipEntry.getCompressedSize()));
switch (method) {
case ZipOutputStream.STORED :
return is;
case ZipOutputStream.DEFLATED :
return new InflaterInputStream(is, new Inflater(true));
default :
throw new ZipException("Unknown compression method " + method);
}
}
/**
* Returns the name of this zip file.
*/
public String getName() {
return name;
}
/**
* Returns the number of entries in this zip file.
*/
public int size() {
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 class PartialInputStream extends InputStream {
private final RandomAccessBuffer raf;
long filepos, end;
public PartialInputStream(RandomAccessBuffer raf, long start, long len) {
this.raf = raf;
filepos = start;
end = start + len;
}
public int available() {
long amount = end - filepos;
if (amount > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
return (int) amount;
}
public int read() throws IOException {
if (filepos == end)
return -1;
synchronized (raf) {
raf.seek(filepos++);
return raf.read();
}
}
public int read(byte[] b, int off, int len) throws IOException {
if (len > end - filepos) {
len = (int) (end - filepos);
if (len == 0)
return -1;
}
synchronized (raf) {
raf.seek(filepos);
int count = raf.read(b, off, len);
if (count > 0)
filepos += len;
return count;
}
}
public long skip(long amount) {
if (amount < 0)
throw new IllegalArgumentException();
if (amount > end - filepos)
amount = end - filepos;
filepos += amount;
return amount;
}
}
private static class RandomAccessFileBuffer extends RandomAccessBuffer {
private final RandomAccessFile raf;
public RandomAccessFileBuffer(RandomAccessFile raf) {
this.raf = raf;
}
/**
* @see RandomAccessBuffer#seek(long)
*/
public void seek(long offset) throws IOException {
raf.seek(offset);
}
/**
* @see RandomAccessBuffer#length()
*/
public long length()
throws IOException {
return raf.length();
}
/**
* @see RandomAccessBuffer#readFully(byte[], int, int)
*/
public void readFully(byte[] data, int offset, int length)
throws IOException {
raf.readFully(data, offset, length);
}
/**
* @see RandomAccessBuffer#skipBytes(int)
*/
public int skipBytes(int count) throws EOFException, IOException {
return raf.skipBytes(count);
}
/**
* @see RandomAccessBuffer#readFully(byte[])
*/
public void readFully(byte[] data) throws IOException {
raf.readFully(data);
}
/**
* @see RandomAccessBuffer#close()
*/
public void close()
throws IOException {
raf.close();
}
/**
* @see RandomAccessBuffer#read()
*/
public int read() throws IOException {
return raf.read();
}
/**
* @see RandomAccessBuffer#read(byte[], int, int)
*/
public int read(byte[] data, int offset, int length)
throws IOException {
return raf.read(data, offset, length);
}
}
private static class RandomAccessByteArrayBuffer extends RandomAccessBuffer {
private final byte[] buffer;
private int pos;
private final int length;
public RandomAccessByteArrayBuffer(byte[] buffer) {
this.buffer = buffer;
this.length = buffer.length;
this.pos = 0;
}
/**
* @see RandomAccessBuffer#seek(long)
*/
public void seek(long offset) throws IOException {
pos = (int)offset;
}
/**
* @see RandomAccessBuffer#length()
*/
public long length()
throws IOException {
return length;
}
/**
* @see RandomAccessBuffer#readFully(byte[])
*/
public void readFully(byte[] data) throws IOException {
readFully(data, 0, data.length);
}
/**
* @see RandomAccessBuffer#readFully(byte[], int, int)
*/
public void readFully(byte[] data, int offset, int len)
throws IOException {
if (pos + len <= length) {
System.arraycopy(buffer, pos, data, offset, len);
pos += len;
} else {
throw new EOFException();
}
}
/**
* @see RandomAccessBuffer#skipBytes(int)
*/
public int skipBytes(int count) throws EOFException, IOException {
if (count > 0) {
count = Math.min(length - pos, count);
pos += count;
return count;
} else {
return 0;
}
}
/**
* @see RandomAccessBuffer#close()
*/
public void close()
throws IOException {
}
/**
* @see RandomAccessBuffer#read()
*/
public int read() throws IOException {
if (pos < length) {
return buffer[pos++] & 0xFF;
} else {
return -1;
}
}
/**
* @see RandomAccessBuffer#read(byte[], int, int)
*/
public int read(byte[] data, int offset, int len)
throws IOException {
if (pos < length) {
len = Math.min(length - pos, len);
System.arraycopy(buffer, pos, data, offset, len);
pos += len;
return len;
} else {
return -1;
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?