关于Class.getResource和ClassLoader.getResource的路径问题
我们都知道,在java中有绝对路径和相对路径之分
绝对路径:以盘符或者/开头的路径。和当前路径没有任何关系
相对路径:不以盘符或者/开头的路径。以当前路径为基准进行计算
例如:
1 System.out.println(new File("").getAbsolutePath()); 2 System.out.println(new File("/").getAbsolutePath());
上述两行代码,的输出结果为:
D:\Eclipse\workspace\PathDemo
D:\
其中PathDemo为我们的工程名,因此这样得到的相对路径是相对于当前工程的路径,而"/"代表根目录,所以直接输出了盘符。
一、下面说明一下关于Class.getResource和ClassLoader.getResource的路径问题
Class.getResource(String path)
path不以’/'开头时,默认是从此类所在的包下取资源;
path 以’/'开头时,则是从bin目录下获取,准确的说是在.class文件所在的目录下
看下面的例子:
1 System.out.println(PathClass.class.getResource("").getPath()); 2 System.out.println(PathClass.class.getResource("/").getPath());
这两行代码输出的结果为:
/D:/Eclipse/workspace/PathDemo/bin/pathdemo/
/D:/Eclipse/workspace/PathDemo/bin/
可以看出,以“/”开头,则是从bin目录下获取,不以"/"开头,则从此类所在的包下获取
如果我们要获取1.txt的路径,用Class.getResource(String path)就有两种写法了,如下
1 System.out.println(PathClass.class.getResource("1.txt").getPath()); 2 System.out.println(PathClass.class.getResource("/pathdemo/1.txt").getPath());
得到的结果为:
/D:/Eclipse/workspace/PathDemo/bin/pathdemo/1.txt
/D:/Eclipse/workspace/PathDemo/bin/pathdemo/1.txt
Class.getClassLoader().getResource(String path)
path不能以’/'开头时;
path是从bin目录下获取;
同样的,我们看下面两行代码
1 System.out.println(PathClass.class.getClassLoader().getResource("").getPath()); 2 System.out.println(PathClass.class.getClassLoader().getResource("/").getPath());
输出结果为:
/D:/Eclipse/workspace/PathDemo/bin/
Exception in thread "main" java.lang.NullPointerException
很显然,不能以“/”开头,否则会报空指针异常。
从而也得到结论:
.class.getResource("/") == Class.getClassLoader().getResource("")
同样的,我们想得到上图中1.txt的路径,只有一种办法,如下
System.out.println(PathClass.class.getClassLoader().getResource("pathdemo/1.txt").getPath());
得到的结果为:
/D:/Eclipse/workspace/PathDemo/bin/pathdemo/1.txt
二、在servlet中,上面的所有内容都有所区别
首先,绝对路径和相对路径有区别,看如下两行代码:
1 System.out.println(new File("").getAbsolutePath()); 2 System.out.println(new File("/").getAbsolutePath());
浏览器产生响应之后,输出结果为:
G:\webEclipse\tomcat7\bin
G:\
可见,以"/"开头的绝对路径没区别,仍然是回到根目录,而不以盘符开头的相对路径则变成了tomcat下的bin目录。
看如下代码:
1 System.out.println(PathServlet.class.getResource("").getPath()); 2 System.out.println(PathServlet.class.getResource("/").getPath()); 3 System.out.println(PathServlet.class.getClassLoader().getResource("").getPath()); 4 System.out.println(PathServlet.class.getClassLoader().getResource("/").getPath());
输出结果为:
/G:/webEclipse/tomcat7/webapps/PathDemo/WEB-INF/classes/pathdemo/
/G:/webEclipse/tomcat7/webapps/PathDemo/WEB-INF/classes/
/G:/webEclipse/tomcat7/webapps/PathDemo/WEB-INF/classes/
/G:/webEclipse/tomcat7/webapps/PathDemo/WEB-INF/classes/
可以看出,Class.getResource和上面完全相同,以“/”开头,则指向该类所在的包的目录下,不以"/"开头,则指向WEB-INF的classes目录。
ClassLoader.getResource则不再限制使用"/"开头,即:对于ClassLoader.getResource,使用"/"与否,都是指向WEB-INF的classes目录。
当然,还有一种方法是使用ServletContext对象的getRealPath的方法,此方法要传入的路径是相对于WebRoot根目录的路径,如下代码:
System.out.println(this.getServletContext().getRealPath(""));
输出结果为:
G:\webEclipse\tomcat7\webapps\PathDemo
可以看出,这种方法得到的路径是指向该web应用的根目录的。