sun.misc.MetaIndex

作用:文件查找的快速拒絕機制

public class MetaIndex {
    private static volatile Map<File, MetaIndex> jarMap;
    private String[] contents;
    // 是否是隻包含 class 的 jar 包
    private boolean isClassOnlyJar;

    public static MetaIndex forJar(File jar) {
        return getJarMap().get(jar);
    }

    public static synchronized void registerDirectory(File dir) {
        // $JAVA_HOME/jre/lib/meta-index
        File indexFile = new File(dir, "meta-index");
        if (indexFile.exists()) {
            try {
                BufferedReader reader = new BufferedReader(new FileReader(indexFile));
                String line = null;
                String curJarName = null;
                boolean isCurJarContainClassOnly = false;
                List<String> contents = new ArrayList<String>();
                Map<File, MetaIndex> map = getJarMap();
                dir = dir.getCanonicalFile();
                line = reader.readLine();
                if (line == null || !line.equals("% VERSION 2")) {
                    reader.close();
                    return;
                }
                while ((line = reader.readLine()) != null) {
                    switch (line.charAt(0)) {
                        case '!':
                        case '#':
                        case '@': {
                            if ((curJarName != null) && (contents.size() > 0)) {
                                map.put(new File(dir, curJarName), new MetaIndex(contents, isCurJarContainClassOnly));
                                contents.clear();
                            }
                            // 當前處理的 jar 包
                            curJarName = line.substring(2);
                            // ! 代表當前 jar 只包含 class 文件
                            if (line.charAt(0) == '!') {
                                isCurJarContainClassOnly = true;
                            } else if (isCurJarContainClassOnly) {
                                isCurJarContainClassOnly = false;
                            }
                            break;
                        }
                        // % 代表註釋
                        case '%':
                            break;
                        default: {
                            contents.add(line);
                        }
                    }
                }
                // 處理最後一個 curJarName 對應的包名
                if ((curJarName != null) && (contents.size() > 0)) {
                    map.put(new File(dir, curJarName), new MetaIndex(contents, isCurJarContainClassOnly));
                }
                reader.close();
            } catch (IOException e) {
                //
            }
        }
    }

    public boolean mayContain(String entry) {
        // 從只有 class 的 jar 包查找非 class 文件返回 false
        if (isClassOnlyJar && !entry.endsWith(".class")) {
            return false;
        }
        String[] conts = contents;
        for (int i = 0; i < conts.length; i++) {
            // 可以看到是通過前綴匹配
            if (entry.startsWith(conts[i])) {
                return true;
            }
        }
        return false;
    }

    // 私有構造方法
    private MetaIndex(List<String> entries, boolean isClassOnlyJar) throws IllegalArgumentException {
        if (entries == null) {
            throw new IllegalArgumentException();
        }
        contents = entries.toArray(new String[0]);
        this.isClassOnlyJar = isClassOnlyJar;
    }

    // dck
    private static Map<File, MetaIndex> getJarMap() {
        if (jarMap == null) {
            synchronized (MetaIndex.class) {
                if (jarMap == null) {
                    jarMap = new HashMap<File, MetaIndex>();
                }
            }
        }
        assert jarMap != null;
        return jarMap;
    }
}
cat /Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/meta-index
For jar file containing only class file, we put '!' before the jar file name; 
for jar file containing only resources file, we put '@' before the jar file name; 
for jar file containing both resources and class file, we put '#' before the jar name. 
% VERSION 2
% WARNING: this file is auto-generated; do not edit
% UNSUPPORTED: this file and its format may change and/or
%   may be removed in a future release
# charsets.jar
sun/nio
sun/awt
# jce.jar
javax/crypto
sun/security
META-INF/ORACLE_J.RSA
META-INF/ORACLE_J.SF
# jfr.jar
oracle/jrockit/
jdk/jfr
com/oracle/jrockit/
! jsse.jar
sun/security
com/sun/net/
! management-agent.jar
@ resources.jar
com/sun/java/util/jar/pack/
META-INF/services/sun.util.spi.XmlPropertiesProvider
META-INF/services/javax.print.PrintServiceLookup
com/sun/corba/
META-INF/services/javax.sound.midi.spi.SoundbankReader
sun/print
META-INF/services/javax.sound.midi.spi.MidiFileReader
META-INF/services/sun.java2d.cmm.CMMServiceProvider
javax/swing
META-INF/services/javax.sound.sampled.spi.AudioFileReader
META-INF/services/javax.sound.midi.spi.MidiDeviceProvider
sun/net
META-INF/services/javax.sound.sampled.spi.AudioFileWriter
com/sun/imageio/
META-INF/services/sun.java2d.pipe.RenderingEngine
META-INF/mimetypes.default
META-INF/services/javax.sound.midi.spi.MidiFileWriter
sun/rmi
javax/sql
META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin
com/sun/rowset/
META-INF/services/javax.print.StreamPrintServiceFactory
META-INF/mailcap.default
java/lang
sun/text
javax/xml
META-INF/services/javax.sound.sampled.spi.MixerProvider
com/sun/xml/
META-INF/services/com.sun.tools.internal.xjc.Plugin
com/sun/java/swing/
com/sun/jndi/
com/sun/org/
META-INF/services/javax.sound.sampled.spi.FormatConversionProvider
! rt.jar
com/sun/java/util/jar/pack/
java/
org/ietf/
com/sun/beans/
com/sun/tracing/
apple/launcher/
com/sun/java/browser/
com/sun/corba/
com/sun/media/
com/sun/awt/
com/sun/management/
sun/
apple/applescript/
com/sun/jmx/
com/sun/demo/
apple/security/
com/sun/imageio/
com/sun/rmi/
com/sun/net/
org/w3c/
com/sun/swing/
com/sun/activation/
apple/laf/
com/sun/nio/
com/sun/rowset/
org/jcp/
com/sun/istack/
jdk/
com/sun/naming/
org/xml/
org/omg/
com/sun/security/
com/sun/image/
com/sun/xml/
com/oracle/
com/sun/java/swing/
com/sun/java_cup/
com/sun/jndi/
com/apple/
com/sun/accessibility/
com/sun/org/
javax/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章