从项目中加载文件
从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; }
路径以/开头,则直接截掉。如果不以/开头,则从当前包下定位资源路径。