⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zipfile.java

📁 Use the links below to download a source distribution of Ant from one of our mirrors. It is good pra
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* *  Licensed to the Apache Software Foundation (ASF) under one or more *  contributor license agreements.  See the NOTICE file distributed with *  this work for additional information regarding copyright ownership. *  The ASF licenses this file to You under the Apache License, Version 2.0 *  (the "License"); you may not use this file except in compliance with *  the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License. * */package org.apache.tools.zip;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.RandomAccessFile;import java.io.UnsupportedEncodingException;import java.util.Calendar;import java.util.Date;import java.util.Enumeration;import java.util.Hashtable;import java.util.zip.Inflater;import java.util.zip.InflaterInputStream;import java.util.zip.ZipException;/** * Replacement for <code>java.util.ZipFile</code>. * * <p>This class adds support for file name encodings other than UTF-8 * (which is required to work on ZIP files created by native zip tools * and is able to skip a preamble like the one found in self * extracting archives.  Furthermore it returns instances of * <code>org.apache.tools.zip.ZipEntry</code> instead of * <code>java.util.zip.ZipEntry</code>.</p> * * <p>It doesn't extend <code>java.util.zip.ZipFile</code> as it would * have to reimplement all methods anyway.  Like * <code>java.util.ZipFile</code>, it uses RandomAccessFile under the * covers and supports compressed and uncompressed entries.</p> * * <p>The method signatures mimic the ones of * <code>java.util.zip.ZipFile</code>, with a couple of exceptions: * * <ul> *   <li>There is no getName method.</li> *   <li>entries has been renamed to getEntries.</li> *   <li>getEntries and getEntry return *   <code>org.apache.tools.zip.ZipEntry</code> instances.</li> *   <li>close is allowed to throw IOException.</li> * </ul> * */public class ZipFile {    private static final int HASH_SIZE = 509;    private static final int SHORT     =   2;    private static final int WORD      =   4;    private static final int NIBLET_MASK = 0x0f;    private static final int BYTE_SHIFT = 8;    private static final int POS_0 = 0;    private static final int POS_1 = 1;    private static final int POS_2 = 2;    private static final int POS_3 = 3;    /**     * Maps ZipEntrys to Longs, recording the offsets of the local     * file headers.     */    private Hashtable entries = new Hashtable(HASH_SIZE);    /**     * Maps String to ZipEntrys, name -> actual entry.     */    private Hashtable nameMap = new Hashtable(HASH_SIZE);    private static final class OffsetEntry {        private long headerOffset = -1;        private long dataOffset = -1;    }    /**     * The encoding to use for filenames and the file comment.     *     * <p>For a list of possible values see <a     * href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.     * Defaults to the platform's default character encoding.</p>     */    private String encoding = null;    /**     * The actual data source.     */    private RandomAccessFile archive;    /**     * Opens the given file for reading, assuming the platform's     * native encoding for file names.     *     * @param f the archive.     *     * @throws IOException if an error occurs while reading the file.     */    public ZipFile(File f) throws IOException {        this(f, null);    }    /**     * Opens the given file for reading, assuming the platform's     * native encoding for file names.     *     * @param name name of the archive.     *     * @throws IOException if an error occurs while reading the file.     */    public ZipFile(String name) throws IOException {        this(new File(name), null);    }    /**     * Opens the given file for reading, assuming the specified     * encoding for file names.     *     * @param name name of the archive.     * @param encoding the encoding to use for file names     *     * @throws IOException if an error occurs while reading the file.     */    public ZipFile(String name, String encoding) throws IOException {        this(new File(name), encoding);    }    /**     * Opens the given file for reading, assuming the specified     * encoding for file names.     *     * @param f the archive.     * @param encoding the encoding to use for file names     *     * @throws IOException if an error occurs while reading the file.     */    public ZipFile(File f, String encoding) throws IOException {        this.encoding = encoding;        archive = new RandomAccessFile(f, "r");        try {            populateFromCentralDirectory();            resolveLocalFileHeaderData();        } catch (IOException e) {            try {                archive.close();            } catch (IOException e2) {                // swallow, throw the original exception instead            }            throw e;        }    }    /**     * The encoding to use for filenames and the file comment.     *     * @return null if using the platform's default character encoding.     */    public String getEncoding() {        return encoding;    }    /**     * Closes the archive.     * @throws IOException if an error occurs closing the archive.     */    public void close() throws IOException {        archive.close();    }    /**     * close a zipfile quietly; throw no io fault, do nothing     * on a null parameter     * @param zipfile file to close, can be null     */    public static void closeQuietly(ZipFile zipfile) {        if (zipfile != null) {            try {                zipfile.close();            } catch (IOException e) {                //ignore            }        }    }    /**     * Returns all entries.     * @return all entries as {@link ZipEntry} instances     */    public Enumeration getEntries() {        return entries.keys();    }    /**     * Returns a named entry - or <code>null</code> if no entry by     * that name exists.     * @param name name of the entry.     * @return the ZipEntry corresponding to the given name - or     * <code>null</code> if not present.     */    public ZipEntry getEntry(String name) {        return (ZipEntry) nameMap.get(name);    }    /**     * Returns an InputStream for reading the contents of the given entry.     * @param ze the entry to get the stream for.     * @return a stream to read the entry from.     * @throws IOException if unable to create an input stream from the zipenty     * @throws ZipException if the zipentry has an unsupported compression method     */    public InputStream getInputStream(ZipEntry ze)        throws IOException, ZipException {        OffsetEntry offsetEntry = (OffsetEntry) entries.get(ze);        if (offsetEntry == null) {            return null;        }        long start = offsetEntry.dataOffset;        BoundedInputStream bis =            new BoundedInputStream(start, ze.getCompressedSize());        switch (ze.getMethod()) {            case ZipEntry.STORED:                return bis;            case ZipEntry.DEFLATED:                bis.addDummy();                return new InflaterInputStream(bis, new Inflater(true));            default:                throw new ZipException("Found unsupported compression method "                                       + ze.getMethod());        }    }    private static final int CFH_LEN =        /* version made by                 */ SHORT        /* version needed to extract       */ + SHORT        /* general purpose bit flag        */ + SHORT        /* compression method              */ + SHORT        /* last mod file time              */ + SHORT        /* last mod file date              */ + SHORT        /* crc-32                          */ + WORD        /* compressed size                 */ + WORD        /* uncompressed size               */ + WORD        /* filename length                 */ + SHORT        /* extra field length              */ + SHORT        /* file comment length             */ + SHORT        /* disk number start               */ + SHORT        /* internal file attributes        */ + SHORT        /* external file attributes        */ + WORD        /* relative offset of local header */ + WORD;    /**     * Reads the central directory of the given archive and populates     * the internal tables with ZipEntry instances.     *     * <p>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.</p>     */    private void populateFromCentralDirectory()        throws IOException {        positionAtCentralDirectory();        byte[] cfh = new byte[CFH_LEN];        byte[] signatureBytes = new byte[WORD];        archive.readFully(signatureBytes);        long sig = ZipLong.getValue(signatureBytes);        final long cfhSig = ZipLong.getValue(ZipOutputStream.CFH_SIG);        while (sig == cfhSig) {            archive.readFully(cfh);            int off = 0;            ZipEntry ze = new ZipEntry();            int versionMadeBy = ZipShort.getValue(cfh, off);            off += SHORT;            ze.setPlatform((versionMadeBy >> BYTE_SHIFT) & NIBLET_MASK);            off += WORD; // skip version info and general purpose byte            ze.setMethod(ZipShort.getValue(cfh, off));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -