Java中的資源路徑引用問題總結

首先來回顧一下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.getSystemResource

這個方法就是個靜態方法, 和 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());
	}

}
相關文章
相關標籤/搜索