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 is= A.class.getResourceAsStream("1.txt");

路径不是以/开头,说明这是一个相对路径,相对的是A.class这个文件,所以,这里的“1.txt”所指的正确位置是与A.class处于同一目录下的1.txt文件,这一文件是存在的,所引不会报错。

如果我们按相对路径的方式通过A去加载2.txt,则路径应该这样描述:

InputStream is= A.class.getResourceAsStream("../2.txt");

是的,用“.."表示上一级目录。

绝对路径:

InputStream is= A.class.getResourceAsStream("/com/github/demo/1.txt");

 5.Class.getResourceAsStream(String path)

Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由ClassLoader获取资源。

如果以‘/’ 开头,则 返回的是classLoader加载器Boot ClassLoader的加载范围,所以返回的也是null,所以不能以 / 开头。

class.getResourceAsStream最终调用是ClassLoader.getResourceAsStream,这两个方法最终调用还是ClassLoader.getResource()方法加载资源。所以上面的规则也适用于此。

事例:
InputStream resourceAsStream = ClassLoader.getSystemResourceAsStream("com/github/demo/1.txt");

转自:https://www.cnblogs.com/haitaofeiyang/p/7737360.html

getResource()的几种路径方式相关推荐

  1. java获取项目中的路径_java中几种获取项目路径方式

    转自http://caodaoxi.iteye.com/blog/1234805 在jsp和class文件中调用的相对路径不同. 在jsp里,根目录是WebRoot 在class文件中,根目录是Web ...

  2. docker 三种挂载文件路径方式

    为何要为容器进行文件挂载 为了持久化docker容器产生的数据(数据文件/配置文件/日志文件), 通常会挂载(映射)产生数据的容器内路径到主机路径上. 用处: 不用进入容器内就能访问配置容器内数据 删 ...

  3. 三十张图片让你彻底弄明白图的两种遍历方式:DFS和BFS

    1 引言   遍历是指从某个节点出发,按照一定的的搜索路线,依次访问对数据结构中的全部节点,且每个节点仅访问一次.图的遍历.遍历过程中得到的顶点序列称为图遍历序列. 2 深度优先搜索 2.1 算法思想 ...

  4. python之路 mysql 博客园_教为学:Python学习之路(二):MySQLdb的几种安装方式,以及用Python测试连接MySql...

    教为学:Python学习之路(二):MySQLdb的几种安装方式,以及用Python测试连接MySql Easy_install安装MySQLdb 很简单,以至于我不晓得该怎么说.一句话. sodu ...

  5. jar容器部署成功无法访问_Spring Boot 应用程序五种部署方式

    翻译自 Deploying Spring Boot Applications[1] 原作者 Murat Artim[2] 可以使用各种方法将 Spring Boot 应用程序部署到生产系统中.在本文中 ...

  6. apache 与 php-fpm 几种处理方式

    原文地址: apache 与 php-fpm 几种处理方式 目录 1.SetHandler 2.ProxyPassMatch 3.ProxyPass <h3 id="1"&g ...

  7. python中if brthon环境安装包_Ant、Gradle、Python三种打包方式的介绍

    今天谈一下Androdi三种打包方式,Ant.Gradle.Python. 当然最开始打包用Ant 很方便,后来转Studio开发,自带很多Gradle插件就用了它,然后随着打包数量越多,打包时间成了 ...

  8. java c3p0 配置文件_【c3p0】 C3P0的三种配置方式以及基本配置项详解

    数据库连接池C3P0框架是个非常优异的开源jar,高性能的管理着数据源,这里只讨论程序本身负责数据源,不讨论容器管理. ---------------------------------------- ...

  9. Windows校验文件哈希hash的两种常用方式

    大家经常都到哪儿去下载软件和应用程序呢?有没想过下载回来的软件.应用程序或资源是否安全呢?在 Windows 10 和 Office 2016 发布当初,很多没权限的朋友都使用第三方网站去下载安装映像 ...

最新文章

  1. KVM之Virtio介绍 (十五)
  2. java split 逗号_java截取之空字符丢失
  3. 客户端相关知识学习(二)之h5与原生app交互的原理
  4. Spark3.1.1 Docker镜像中修改/etc/hosts
  5. vi / vim 字符替换详解
  6. linux常用特殊符号
  7. 传智播客 c#_播客#46:Alexander Kallaway
  8. leetcode. Intersection of Two Linked Lists
  9. MockServer 服务框架设计
  10. 如何设计更好的脉搏血氧仪:实施
  11. 【深度好文】二维图像傅里叶变换 YYDS
  12. 电脑输入法变成繁体中文如何改回来
  13. VSCode配置git图文
  14. 2019年读书记录及总结
  15. 形象解释清了内存颗粒、单双面、主板布线和双通道的那些事儿
  16. aircrack-ng for windows的简单使用教程
  17. 复位的recovery time和removal time
  18. 基于FPGA的一维卷积神经网络CNN的实现(一)框架
  19. 后端开发——Flask框架从入门到入坟(中)
  20. 关于信噪比与向已知信号添加噪声的整理及个人心得

热门文章

  1. NXP S32K1 FlexTimer模块
  2. Linux Mint + win10 双系统初体验
  3. 金山卫士开源软件之旅(十) KSafeMainproject的分析 1
  4. Echarts动态生成图表,图表类型进行切换,长数据区域展示
  5. win32创建窗口及其消息循环
  6. 【XSY3126】异或II 数学
  7. 关于解决NAT 类型显示“Teredo 无法获得资格”的一个案例
  8. numpy之数组的赋值
  9. 性能测试时那些「难以启齿」的问题-CPU相关
  10. 电路中的VDD,DVDD,AVDD,VCC,AFVDD,DOVDD,IOVDD的区别