首先來回顧一下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()); } }