[b]一、Class#getResourceAsStream[/b]
[b]1.1 JDK定义[/b]
查找具有给定名称的资源。查找与给定类相关的资源的规则,是通过定义类的 class loader 实现的。此方法委托此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResourceAsStream(java.lang.String)。
在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:
(1)如果 name 以 '/' 开始 ('\u002f'),则绝对资源名是 '/' 后面的 name 的一部分。
(2)否则,绝对名具有以下形式:
modified_package_name/name
其中 modified_package_name 是此对象的[color=red]包名[/color],该名用 '/' 取代了 '.' ('\u002e')。
[b]参数: [/b]
name - 所需资源的名称
返回:
一个 InputStream 对象;如果找不到带有该名称的资源,则返回 null
抛出:
NullPointerException - 如果 name 是 null
从以下版本开始:
JDK1.1
[b]此方法参数是与getResouce()方法一样的,它相当于你用getResource()取得File文件后,再new InputStream(file)一样的结果。[/b]
[b]二、Class#getResource[/b]
[b]2.1 JDK定义[/b]
[url]public URL getResource(String name)[/url]
查找带有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。此方法委托给此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResource(java.lang.String)。
在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:
(1)如果 name 以 '/' ('\u002f') 开始,则绝对资源名是 '/' [color=red]后面的 name 的一部分[/color]。
(2)否则,绝对名具有以下形式:
modified_package_name/name
其中 modified_package_name 是此对象的包名,该名用 '/' 取代了 '.' ('\u002e')。
[b]参数: [/b]
name - 所需资源的名称
返回:
一个 URL 对象;如果找不到带有该名称的资源,则返回 null
从以下版本开始:
JDK1.1
[b]2.2 举例说明[/b]
包路径:
[img]http://dl2.iteye.com/upload/attachment/0102/6936/05321984-c477-3bda-9f4a-1f7e81a85259.bmp[/img]
Ehcache.java的内容:
[b]解释:[/b]
1.路径开头不带”/”的会当做是相对当前类(class文件)的文件路径,比如第一行输出没有指明任何文件,而且路径开头不带”/”,则取得的是当前class的路径,也就是包路径。
第4行输出则找不到文件,因为不带”/”,所以是相对当前class的相对路径,从图中我们可以看到ehcache.class的包路径下没有conf/ehcache.xml文件。
2.路径开头带”/”的是绝对路径,是相对classpath的路径。如第二行的输出,classpath就是/E:/anWorkSpace/pra_test/target/classes/。
第三行的输出就是相对classpath路径,加上绝对路径的”/”后面的部分。
[b]总结[/b]:
可以看到Class的这两个方法都是跟ClassLoader相关的,也就是跟class的路径和classpath路径相关。这与开发工具IDE无关,请看下面:
比如在上面的main方法里写写new File就要写成:
才可以在IDE环境下运行main方法。但是[color=red]发布打包之后这又要报错找不到文件[/color],为什么呢?因为IDE里File的相对路径是相对IDE的工程根路径,也就是System.getProperties(“user.dir”)的路径。
new File(path),这个方法的路径到底在那里取决于调用[b]java命令的起始位置定义[/b]在哪里,tomcat/bin下面的catalina.bat调用了java,所以在tomcat下相对起始位置是tomcat/bin,但是eclipse启动时,起始位置是eclipse的项目路径。
[b]三、ClassLoader#getResource[/b]
[b]3.1 JDK定义[/b]
public URL getResource(String name)
查找具有给定名称的资源。资源是可以通过类代码以与代码路径无关的方式访问的一些数据(图像、声音、文本等)。
资源名称是以 '/' 分隔的标识资源的路径名称。
此方法首先搜索资源的父类加载器;如果父类加载器为 null,则搜索的路径就是虚拟机的内置类加载器的路径。如果搜索失败,则此方法将调用 findResource(String) 来查找资源。
参数:
name - 资源名称
返回:
读取资源的 URL 对象;如果找不到该资源,或者调用者没有足够的权限获取该资源,则返回 null。
从以下版本开始:
1.1
[b]3.2 举例说明[/b]
Ehcache.java的内容:
可以看出通过classLoader获取classpath的参数跟Class的不太一样。但原理基本一致,因为Class的方法是调用ClassLoader的对应方法实现的,只是入参做了点点处理。
ClassLoader把决定权交给了类加载器,例如tomcat的类加载是非委托机制的,而weblogic的类加载是委托的。
ClassLoader的getResourceAsStream方法与它的getResource方法的关系跟Class的两个方法是一样的。
还可以参考:
[url]http://blog.csdn.net/fancylovejava/article/details/7577294[/url]
[url]http://blog.sina.com.cn/s/blog_9386f17b0100w2vv.html[/url]
[url]http://lavasoft.blog.51cto.com/62575/265821/[/url]
[url]http://lavasoft.blog.51cto.com/62575/265821/[/url]
[url]http://www.iteye.com/topic/483115[/url]
最后一篇提到,可以使用XWork的工具类ClassLoaderUtil读取jar包里的资源文件等。
[b]1.1 JDK定义[/b]
public InputStream getResourceAsStream(String name)
查找具有给定名称的资源。查找与给定类相关的资源的规则,是通过定义类的 class loader 实现的。此方法委托此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResourceAsStream(java.lang.String)。
在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:
(1)如果 name 以 '/' 开始 ('\u002f'),则绝对资源名是 '/' 后面的 name 的一部分。
(2)否则,绝对名具有以下形式:
modified_package_name/name
其中 modified_package_name 是此对象的[color=red]包名[/color],该名用 '/' 取代了 '.' ('\u002e')。
[b]参数: [/b]
name - 所需资源的名称
返回:
一个 InputStream 对象;如果找不到带有该名称的资源,则返回 null
抛出:
NullPointerException - 如果 name 是 null
从以下版本开始:
JDK1.1
[b]此方法参数是与getResouce()方法一样的,它相当于你用getResource()取得File文件后,再new InputStream(file)一样的结果。[/b]
[b]二、Class#getResource[/b]
[b]2.1 JDK定义[/b]
[url]public URL getResource(String name)[/url]
查找带有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。此方法委托给此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResource(java.lang.String)。
在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:
(1)如果 name 以 '/' ('\u002f') 开始,则绝对资源名是 '/' [color=red]后面的 name 的一部分[/color]。
(2)否则,绝对名具有以下形式:
modified_package_name/name
其中 modified_package_name 是此对象的包名,该名用 '/' 取代了 '.' ('\u002e')。
[b]参数: [/b]
name - 所需资源的名称
返回:
一个 URL 对象;如果找不到带有该名称的资源,则返回 null
从以下版本开始:
JDK1.1
[b]2.2 举例说明[/b]
包路径:
[img]http://dl2.iteye.com/upload/attachment/0102/6936/05321984-c477-3bda-9f4a-1f7e81a85259.bmp[/img]
Ehcache.java的内容:
public static void main(String[] args)
{
// 1输出: /E:/anWorkSpace/pra_test/target/classes/com/anning/cache/
System.out.println(Ehcache.class.getResource("").getFile());
// 2输出: /E:/anWorkSpace/pra_test/target/classes/
System.out.println(Ehcache.class.getResource("/").getFile());
// 3输出: /E:/anWorkSpace/pra_test/target/classes/conf/ehcache.xml System.out.println(Ehcache.class.getResource("/conf/ehcache.xml").getFile());
// 4输出: null
System.out.println(Ehcache.class.getResource("conf/ehcache.xml"));
}
[b]解释:[/b]
1.路径开头不带”/”的会当做是相对当前类(class文件)的文件路径,比如第一行输出没有指明任何文件,而且路径开头不带”/”,则取得的是当前class的路径,也就是包路径。
第4行输出则找不到文件,因为不带”/”,所以是相对当前class的相对路径,从图中我们可以看到ehcache.class的包路径下没有conf/ehcache.xml文件。
2.路径开头带”/”的是绝对路径,是相对classpath的路径。如第二行的输出,classpath就是/E:/anWorkSpace/pra_test/target/classes/。
第三行的输出就是相对classpath路径,加上绝对路径的”/”后面的部分。
[b]总结[/b]:
可以看到Class的这两个方法都是跟ClassLoader相关的,也就是跟class的路径和classpath路径相关。这与开发工具IDE无关,请看下面:
比如在上面的main方法里写写new File就要写成:
new File(“src/main/resources/conf/ehcache.xml”);
才可以在IDE环境下运行main方法。但是[color=red]发布打包之后这又要报错找不到文件[/color],为什么呢?因为IDE里File的相对路径是相对IDE的工程根路径,也就是System.getProperties(“user.dir”)的路径。
new File(path),这个方法的路径到底在那里取决于调用[b]java命令的起始位置定义[/b]在哪里,tomcat/bin下面的catalina.bat调用了java,所以在tomcat下相对起始位置是tomcat/bin,但是eclipse启动时,起始位置是eclipse的项目路径。
[b]三、ClassLoader#getResource[/b]
[b]3.1 JDK定义[/b]
public URL getResource(String name)
查找具有给定名称的资源。资源是可以通过类代码以与代码路径无关的方式访问的一些数据(图像、声音、文本等)。
资源名称是以 '/' 分隔的标识资源的路径名称。
此方法首先搜索资源的父类加载器;如果父类加载器为 null,则搜索的路径就是虚拟机的内置类加载器的路径。如果搜索失败,则此方法将调用 findResource(String) 来查找资源。
参数:
name - 资源名称
返回:
读取资源的 URL 对象;如果找不到该资源,或者调用者没有足够的权限获取该资源,则返回 null。
从以下版本开始:
1.1
[b]3.2 举例说明[/b]
Ehcache.java的内容:
public static void main(String[] args)
{
// 1输出: file:/E:/anWorkSpace/pra_test/target/classes/
System.out.println(Ehcache.class.getClassLoader().getResource(""));
// 2输出: null
System.out.println(Ehcache.class.getClassLoader().getResource("/"));
//3输出:file:/E:/anWorkSpace/pra_test/target/classes/conf/ehcache.xml
System.out.println(Ehcache.class.getClassLoader().getResource("conf/ehcache.xml"));
}
可以看出通过classLoader获取classpath的参数跟Class的不太一样。但原理基本一致,因为Class的方法是调用ClassLoader的对应方法实现的,只是入参做了点点处理。
ClassLoader把决定权交给了类加载器,例如tomcat的类加载是非委托机制的,而weblogic的类加载是委托的。
ClassLoader的getResourceAsStream方法与它的getResource方法的关系跟Class的两个方法是一样的。
还可以参考:
[url]http://blog.csdn.net/fancylovejava/article/details/7577294[/url]
[url]http://blog.sina.com.cn/s/blog_9386f17b0100w2vv.html[/url]
[url]http://lavasoft.blog.51cto.com/62575/265821/[/url]
[url]http://lavasoft.blog.51cto.com/62575/265821/[/url]
[url]http://www.iteye.com/topic/483115[/url]
最后一篇提到,可以使用XWork的工具类ClassLoaderUtil读取jar包里的资源文件等。