首先我用的是Mac环境, Maven项目; 如图项目结构如下:
话不多说,上代码:
先看 getClass().getResource
public void test1() throws IOException {
System.out.println(this.getClass().getResource(""));
// file:/usr/eclipse/my_workspace/test.path/target/classes/com/test/sh/
// 是类所在的 绝对路径 (就是类的包目录绝对路径)
System.out.println(this.getClass().getResource("/"));
// file:/usr/eclipse/my_workspace/test.path/target/classes/
// 项目的CLASSPATH 根目录
System.out.println(this.getClass().getResource("/test.sh"));
// file:/usr/eclipse/my_workspace/test.path/target/classes/test.sh
// 去项目的CLASSPATH 目录下 寻找文件
System.out.println(this.getClass().getResource("/subfile/test22.sh"));
// file:/usr/eclipse/my_workspace/test.path/target/classes/subfile/test22.sh
// 去项目的CLASSPATH 下 特定的目录寻找文件, 有几层写几层
}
测试的结果是输出结果写在代码下面的注释里 ; 再看下 Class.getClassLoader().getResource(String path);
public void test2() {
//测试: Class.getClassLoader().getResource(String path);
System.out.println(this.getClass()); //输出: class com.test.sh.TestPath
System.out.println(this.getClass().getClassLoader()); //输出: sun.misc.Launcher$AppClassLoader@4554617c
System.out.println(this.getClass().getClassLoader().getResource(""));
//结果: file:/usr/eclipse/my_workspace/test.path/target/classes/
// 项目的CLASSPATH 根目录
System.out.println(this.getClass().getClassLoader().getResource("/")); //结果: null 说明这种不能以’/'开头时;
System.out.println(this.getClass().getClassLoader().getResource("/test.sh")); // 同样为空
System.out.println(this.getClass().getClassLoader().getResource("test.sh"));
//结果: file:/usr/eclipse/my_workspace/test.path/target/classes/test.sh
System.out.println(this.getClass().getClassLoader().getResource("subfile/test22.sh"));
//结果: file:/usr/eclipse/my_workspace/test.path/target/classes/subfile/test22.sh
}
接下来是:
public void test3() {
System.out.println(System.getProperty("user.dir"));
// 结果:/usr/eclipse/my_workspace/test.path
//当前工程路径
}
public void test4() {
System.out.println(System.getProperty("java.class.path"));
// 结果:/usr/eclipse/my_workspace/test.path/target/classes
// 当前工程的 classpath 路径
}
然后是:
public void test5() throws IOException {
File f = new File( "test_class_getResourceAsStream.txt" );
System.out.println( f.getAbsolutePath() );
InputStream resourceAsStream = this.getClass().getResourceAsStream("/test.sh");
// 如果以 '/' 开头的,那么就会从classpath的根路径下开始查找指定的文件。
inputstreamToFile( resourceAsStream, f );
}
接着测试 Class.getResourceAsStream 和ClassLoader.getResourceAsStream :
public void test6() throws IOException {
File f = new File( "test_Class_getClassLoader_getResourceAsStream.txt" );
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("test22.sh");
//不能以 '/' 开头 ; 从classpath的根路径下开始查找指定的文件
InputStream resourceAsStream2 = this.getClass().getClassLoader().getResourceAsStream("subfile/test22.sh");
//不能以 '/' 开头 ; 从classpath的根路径下开始查找指定的文件。有几层写几层
inputstreamToFile( resourceAsStream, f );
}
public static void inputstreamToFile(InputStream ins, File file) throws IOException {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
}
好了看了这么多代码的测试, 也是眼花缭乱, 不要急, 静下来总结的时候到了. 从结果来看:
【 this.getClass().getResource("/") == this.getClass().getClassLoader().getResource("") 】
Class.getResource和Class.getResourceAsStream在使用时路径选择上是一样的。
Class.getClassLoader().getResource和Class.getClassLoader().getResourceAsStream在使用时路径选择上也是一样的。
我们可以总结到:
1. Class.getResourceAsStream(String path) :
不以'/'开头时默认是从此类所在的包下取资源,以'/'开头则是从ClassPath 根下获取,多次目录时, 文件有几层写几层。
跟源码发现其只是通过path构造一个绝对路径,最终还是由ClassLoader获取资源。
2. Class.getClassLoader.getResourceAsStream(String path) :
默认则是从ClassPath根下获取,path不能以'/'开头,否则会报错; 多次目录时, 还是中间的子目录几层写几层
写在最后: 可以自己复制这些测试代码, 然后自己测试一下, 基本上这些文件在不同的位置怎么获取都了如指掌了! 您说呢.