从项目中加载文件

从main/java/resources目录下加载文件时,可以通过Class.getResource("/xxx.txt")和Classloader.getResource("xxx.txt")来加载文件。

使用Class.getResource加载资源时,路径带/表示从classpath加载资源,不带表示从此类所在包下取资源。

使用Classloader.getResource加载资源时,路径带/表示从boot classloader的加载范围中寻找资源;不带/表示从类加载器的加载范围加载资源,基于classloader机制,如果当前无法找到,会逐级向上委托加载直至到boot classloader。

Class.getResource("/xxx.txt")和Classloader.getResource("xxx.txt")底层逻辑一致,路径上的差别在具体执行时已经被去除。

public java.net.URL getResource(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResource(name);
        }
        return cl.getResource(name);
    }

路径的处理在resolveName上,

    private String resolveName(String name) {
        if (name == null) {
            return name;
        }
        if (!name.startsWith("/")) {
            Class<?> c = this;
            while (c.isArray()) {
                c = c.getComponentType();
            }
            String baseName = c.getName();
            int index = baseName.lastIndexOf('.');
            if (index != -1) {
                name = baseName.substring(0, index).replace('.', '/')
                    +"/"+name;
            }
        } else {
            name = name.substring(1);
        }
        return name;
    }

路径以/开头,则直接截掉。如果不以/开头,则从当前包下定位资源路径。

原文地址:https://www.cnblogs.com/asfeixue/p/9233041.html