首先来回顾一下java文件的执行:java
假设有这样一个文件结构
在 root路径下,有com/a/A.class
如今在root路径的命令行下 执行
bash
java A;
这样确定会报错:找不到或没法加载主类,由于当前路径下没有A这个类啊!!测试
正确的执行方法:spa
java com.a.A
若是我要在非root路径下运行A类,怎么搞:命令行
java -cp root com.a.A
也就是说用cp命令,将root路径引入到classpath中,这样,加载器加载com.a.A的时候,就会去咱们传入的classpath中去寻找了。
这是classpath的简单用法。code
当咱们不手动指定classpath的时候,classpath就是当前路径,也就是执行java命令的地方。ci
搞清楚这些,再来讲明资源路径引用的问题。
new File("a.txt");
new FileInputStream("a.txt");
如以上两行代码,用的都是相对路径,那么程序在运行的时候就会在当前程序运行的路径下,而不是在classpath中寻找文件(这一点很重要)。资源
再来看经过类和类加载器获取资源的方式:
1. 经过类获取资源
文档
A.class.getResource("b.txt")
1) 若是是相对路径,会在当前类所在的路径下找,即 com.a下面get
2) 若是以/开始,则从根路径去找
2. 经过类加载器获取资源
A.class.getClassLoader().getResource("a.txt")
会在classpath找,而classpath是能够在运行时传入的。例如
java -cp a/b/c A 那么类加载器也会在a/b/c路径下去找
注意,根据这个方法的API文档说明,其路径分隔符必须是/。
注意:
1. 不管上述2种方式, 对于打完jar包后, 都只能获取jar包内的文件, 而不能获取jar包外的文件.
该目录是运行java命令的那个文件夹, 即用户当前工做目录!
用户主目录的获取方式:1. System.getProperty("user.dir") 2. new File(".").getAbsolutePath()
这个用户主目录和jar包所在目录没有任何关系, 由于程序不必定在jar包的目录下运行.
这个方法就是个静态方法, 和 ClassLoader的 getResource 方法比较相似.
总结:
1. io流包括new File() 引用都是 从 程序运行的路径下找。
2. 经过类获取资源:会在类的包路径找
3. 经过类加载器获取资源:会在classpath中找
获取资源路径总结
序号 | 代码 | 做用 |
---|---|---|
1 | System.getProperty("user.dir") | 用户目录 |
2 | new File(".") | 用户目录 |
3 | Main.class.getResource("config.properties") | Main类所在包下找config.properties文件 |
4 | Main.class.getResource("/config.properties") | 从根目录下(顶层包的同级目录)找 |
5 | Main.class.getClassLoader().getResource("config.properties") | 从根目录下(顶层包的同级目录)找 |
6 | Main.class.getClassLoader().getResource("/config.properties") | null |
7 | ClassLoader.getSystemResource("config.properties") | 从根目录下(顶层包的同级目录)找 |
测试代码:
public class Main { public static void main(String[] args) { // 用户主目录 System.out.println("user.dir: "+System.getProperty("user.dir")); System.out.println("new File: "+new File(".").getAbsolutePath()); System.out.println("\nClass 相对路径: "+Main.class.getResource("config.properties").getPath()); System.out.println("Class 绝对路径: "+Main.class.getResource("/config.properties").getPath()); System.out.println("\nClassLoader 相对路径: "+Main.class.getClassLoader().getResource("config.properties").getPath()); System.out.println("ClassLoader 绝对路径: "+Main.class.getClassLoader().getResource("/config.properties")); System.out.println("\nClassLoader.getSystemResource: "+ClassLoader.getSystemResource("config.properties").getPath()); } }