java getresourceasstream null_java踩坑记-getResourceAsStream

本文主要是研究下面集中方法到底谁才能真正的load到文件,你能一眼看出来吗?

GetResourcesSample.class.getClassLoader.getResourceAsStream("main-resources-file.txt")

GetResourcesSample.class.getClass().getResourceAsStream("main-resources-file.txt")

GetResourcesSample.class.getResourceAsStream("main-resources-file.txt")

GetResourcesSample.class.getClassLoader.getResourceAsStream("/main-resources-file.txt")

GetResourcesSample.class.getClass().getResourceAsStream("/main-resources-file.txt")

GetResourcesSample.class.getResourceAsStream("/main-resources-file.txt")

很晕吧,反正我是挺晕的。

目录结构:

e68b93ae18f44f1e39b166fc10979fcd.png

代码:

public classGetResourcesSample {private static final String MAIN_FILE = "main-resources-file.txt";private static final String MAIN_FILE_WITH_SLASH = "/main-resources-file.txt";private static final String TEST_FILE = "test-resources-file.txt";private static final String TEST_FILE_WITH_SLASH = "/test-resources-file.txt";private static final String ROOT_FILE = "project-root-file.txt";private static final String ROOT_FILE_WITH_SLASH = "./project-root-file.txt";public static voidmain(String[] args) {

validateResult(MAIN_FILE);

validateResult(MAIN_FILE_WITH_SLASH);

validateResult(TEST_FILE);

validateResult(TEST_FILE_WITH_SLASH);

validateResult(ROOT_FILE);

validateResult(ROOT_FILE_WITH_SLASH);

}private static voidvalidateResult(String file) {

InputStream inputStream1= GetResourcesSample.class.getClass().getResourceAsStream(file);if (inputStream1 != null) {

System.out.println(MessageFormat

.format("GetResourcesSample.class.getClass().getResourceAsStream(\"{0}\") is not null!", file));

}

InputStream inputStream2= GetResourcesSample.class.getResourceAsStream(file);if (inputStream2 != null) {

System.out.println(

MessageFormat.format("GetResourcesSample.class.getResourceAsStream(\"{0}\") is not null!", file));

}

InputStream inputStream3= GetResourcesSample.class.getClassLoader().getResourceAsStream(file);if (inputStream3 != null) {

System.out.println(

MessageFormat.format("GetResourcesSample.class.getClassLoader().getResourceAsStream(\"{0}\") is not null!", file));

}

}

}

结果:

GetResourcesSample.class.getClassLoader().getResourceAsStream("main-resources-file.txt") is not null!

GetResourcesSample.class.getClass().getResourceAsStream("/main-resources-file.txt") is not null!

GetResourcesSample.class.getResourceAsStream("/main-resources-file.txt") is not null!

结论:

Class.getResourceAsStream 最终调用的是此Class的Class Loader的getResourceAsStream来进行读文件(有些绕,尽量理解)

GetResourcesSample.class.getClass() 得到的是Class这个类的实例,它的ClassLoader是JVM的bootstrap Class Loader

GetResourcesSample.class.getResourceAsStream 由于去resolve了一下name,虽然是当前class的ClassLoader,它也读不到这个文件;除非你的文件名以“/”开头。详见源代码:

/*** Add a package name prefix if the name is not absolute Remove leading "/"

* if name is absolute*/

privateString resolveName(String name) {if (name == null) {returnname;

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

}returnname;

}

project-root-file.txt这种最后最终不被打在Jar包里的文件,是没有机会被读取的,除非hard code一个文件所在的绝对路径

把相同代码放到UT里面去跑,会发现UT能同时load到main和test下的文件。因为JUnit有它自己的ClassLoader,它能同时读到main和test下的文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值