使用idea時候遇到的一些輸出檔案或者讀取檔案路徑問題
Java里加載Properties檔案都是通過Java.util包裡的Properties類的load()方法來載入一個Properties配置檔案,load()方法需要接收一個檔案輸入流,而InputStream的構建需要Java.io.File物件,即new FileInputStream(new File(path));現在問題就集中在如何動態獲取這個路徑。
下面以一個示例來說明吧。如圖:
現在ActionFactory類裡需要讀取src目錄下的config.properties檔案。我們知道,java web專案編譯後src目錄對應的是應該是WEB-INF下的classes目錄,所以我們可以先獲取到ActionFactory.class檔案,再根據相對路徑採用../一步一步返回上一級得到config.properties檔案的路徑,於是有了第一種寫法:
InputStream stream = this.getClass().getResourceAsStream("../../../../config.properties");//這裡的this指的是ActionFActory類
pro.load(stream);
當然我們也可以通過類載入器根據一個相對路徑返回一個檔案輸入流,即ClassLoader的getResourceAsStream方法。我們知道專案裡的所有java檔案編譯後最終都是相對於WEB-INF下的classes目錄存放的,而config.properties檔案釋出後的路徑剛好是以classes目錄為根目錄。
所以我們通過專案裡的類獲取類載入器從而得到檔案流,於是又有了第二種寫法:
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("config.properties");
pro.load(stream);
注意這裡的this指的是ActionFActory類,當然你可以把它換成專案裡的其他自定義類,因為專案裡類雖不同,但都是使用的同一類
載入器。但是還要注意一點的是,注意我上面綠色標識的內容,是其他自定義類,而不能換成其他任意類。比如java.lang.Thread類就不行。這是你肯定會有這個疑問:為什麼通過Thread類得不到類載入器?這個還得從JVM載入類說起。JVM啟動時會首先使用JVM預設的系統類載入器幫我們載入一些jar,那到底JVM都自動幫我們載入了那些JAR檔案到記憶體去了呢?具體請看圖:
也就是說,如圖所示紅色方框表示的jar裡的所有類.getClassLoader()得到的都是null,因為它們都是由JVM系統類載入器載入的,而Java的安全機制是不允許你獲取系統類載入器物件的。
理解了上面那些,那我們還可以這樣寫:
InputStream stream=Thread.currentThread().getClass().getResourceAsStream("/config.properties");
但不能這樣寫:
InputStream stream = Thread.currentThread().getClass().getClassLoader().getResourceAsStream("config.properties");
但可以這樣寫:
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("config.properties");
InputStream stream = new FileInputStream("/config.properties"); //相對於專案web-inf/classes目錄
為什麼 我就不再解釋了吧。
如果是在web專案中,我們還可以這樣寫:
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties");
不過servlet已經幫我們封裝了,我們一般這樣寫:
ServletContext.getRealPath("/") 這裡的斜槓是相對與專案部署後的WebRoot為根目錄。