【知识碎片】getResource和getResourceAsStream
1. 前言
在Java中获取资源的时候,经常用到getResource和getResourceAsStream,本文总结一下这两种获取资源文件的路径差异。
2.Class.getResource(String path)
path不以'/'开头时,默认是从此类所在的包下取资源;
path以'/'开头时,则是从项目的ClassPath根下获取资源。在这里'/'表示ClassPath的根目录。
JDK设置这样的规则,是很好理解的,path不以'/'开头时,我们就能获取与当前类所在的路径相同的资源文件,而以'/'开头时可以获取ClassPath根下任意路径的资源。
如下所示的例子:

public class Test
{
public static void main(String[] args)
{
System.out.println(Test.class.getResource(""));
System.out.println(Test.class.getResource("/"));
}
}

运行结果为:
file:/D:/work_space/java/bin/net/swiftlet/
file:/D:/work_space/java/bin/
3.Class.getClassLoader().getResource(String path)
path不能以'/'开头,path是指类加载器的加载范围,在资源加载的过程中,使用的逐级向上委托的形式加载的,'/'表示Boot ClassLoader,类加载器中的加载范围,因为这个类加载器是C++实现的,所以加载范围为null。如下所示:

public class Test
{
public static void main(String[] args)
{
System.out.println(Test.class.getClassLoader().getResource(""));
System.out.println(Test.class.getClassLoader().getResource("/"));
}
}

运行结果为:
file:/D:/work_space/java/bin/
null
从上面可以看出:
class.getResource("/") == class.getClassLoader().getResource("")
其实,Class.getResource和ClassLoader.getResource本质上是一样的,都是使用ClassLoader.getResource加载资源的。下面请看一下jdk的Class源码:

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);
}

从上面就可以看才出来:Class.getResource和ClassLoader.getResource本质上是一样的。至于为什么Class.getResource(String path)中path可以'/'开头,是因为在name = resolveName(name);进行了处理:

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;
}

4.Class.getResourceAsStream(String path)
path不以'/'开头时,默认是指所在类的相对路径,从这个相对路径下取资源;
path以'/'开头时,则是从项目的ClassPath根下获取资源,就是要写相对于classpath根下的绝对路径。
举例就明白了:

com
|-github
|-demo
| |-A.class
| |-1.txt
|-B.class
|-2.txt

InputStream resourceAsStream = ClassLoader.getSystemResourceAsStream("com/github/demo/1.txt");
【知识碎片】getResource和getResourceAsStream的更多相关文章
- IOS开发基础知识碎片-导航
1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...
- getResource和getResourceAsStream
1. 前言 在Java中获取资源的时候,经常用到getResource和getResourceAsStream,本文总结一下这两种获取资源文件的路径差异. 2.Class.getResource(St ...
- [转]getResource()和getResourceAsStream以及路径问题
原文链接:http://blog.sina.com.cn/s/blog_4b5bc0110100g22w.html 用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉 ...
- getResource()和getResourceAsStream以及路径问题【转】【补】
一 getResource 用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉颇深,大常最经常用的,就是用JAVA的File类,如要取得c:/test.txt文件,就 ...
- getResource()和getResourceAsStream以及路径问题
用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉颇深,大常最经常用的,就是用JAVA的File类,如要取得c:/test.txt文件,就会这样用File file ...
- getResource()和getResourceAsStream以及路径问题(转)
用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉颇深,大常最经常用的,就是用JAVA的File类,如要取得c:/test.txt文件,就会这样用File file ...
- class.getResource()和getResourceAsStream的用法
转自:http://blog.csdn.net/lcj8/article/details/3502849 class.getResource()的用法 用JAVA获取文件,听似简单,但对于很多像我这样 ...
- java读取配置文件的推荐方法getResource、getResourceAsStream
在java开发中经常会读取配置文件,如果把文件路径写死,就太LOW了,也不符合编码规范. 在网上找了一些资料后,发现有两种方法:xxx.class.getResource("") ...
- getResource()和getResourceAsStream()以及路径问题
用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉颇深,大常最经常用的,就是用JAVA的File类,如要取得c:/test.txt文件,就会这样用File file ...
随机推荐
- Redis缓存使用技巧
缓存能够有效加速应用的访问速度,同时可以降低后端负载,在应用架构中起着至关重要的作用,本文主要介绍缓存使用的一些技巧. 缓存更新策略 LRU/LFU/FIFO算法剔除 场景:数据一致性要求较低 原理: ...
- [SCOI2012] 喵星球上的点名
Description 给定 \(N\) 个姓名串和 \(M\) 个点名串.询问每个点名串点到了多少姓名和每个姓名串被点到了几次.\(N\leq 5\cdot 10^4,M\leq 10^5\). S ...
- [转]npm、 cnpm、yarn
本文转自:https://blog.csdn.net/sinat_34682450/article/details/79473658 终于搞懂了三者之间的关系- 要知道三者之间的关系首先要了解三个包管 ...
- c# Cache 使用实例
/// <summary> /// 创建缓存项的文件 /// </summary> /// <param name="key">缓存Key< ...
- oracle的start with connect by prior
oracle的start with connect by prior是根据条件递归查询"树",分为四种使用情况: 第一种:start with 子节点ID='...' connec ...
- HTML中body与html的关系
转载自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com] 一.相关基础 一个div块级元素没有主动为其设置宽度和高度,浏览器会为其分配可使用的最大宽度(比如全屏宽度),但是不 ...
- php文件与HTML页面的数据交互
注意:首先需要保证本地配置了php开发环境,如WAMP开发环境 WAMP配置:https://www.cnblogs.com/shiyiaccn/p/9984579.html php获取HTML页面返 ...
- React中props
今天让我们开启新的篇章好吧,来搞一搞React,以下所有操作都是我个人的一些理解,如果有错吴还请指出,想要看更全的可以去React官网可能一下子好吧 昨天按摩没到位,导致今天身体不太行,撸码千万别苦了 ...
- python之锁, 队列
进程的其他方法 进程id,进程名字,查看进程是否活着is_alive() terminate()发送结束进程的信号 import time import os from multiprocessin ...
- python正则表达式模块re:正则表达式常用字符、常用可选标志位、group与groups、match、search、sub、split,findall、compile、特殊字符转义
本文内容: 正则表达式常用字符. 常用可选标志位. group与groups. match. search. sub. split findall. compile 特殊字符转义 一些现实例子 首发时 ...