Java程序中的路徑問題

1 Java程序中的路徑問題

1.1 背景描述

本文討論的是非web項目中java程序的路徑問題。
在咱們編寫的Java程序中,須要絕對路徑來定位到當前程序所在的路徑。咱們獲取了這個絕對路徑的變量值後,傳遞給Log4j日誌框架,從而實現輸出日誌路徑是動態的。
具體來講,是實現下面的預期。
1 當不在程序所在的目錄下執行jar文件時,程序中的絕對路徑仍然能生效。(即不是指向用戶目錄)。
2 實現Log4j輸出的日誌文件可以位於程序所在的目錄。(不須要額外的手工指定程序所在目錄,動態的實現)。java

1.2 問題定位

1 絕對路徑的獲取。
2 帶依賴jar包的打jar包與程序路徑問題。
3 獲取了絕對路徑的變量值後,如何傳遞給Log4j日誌框架,與相關的配置。git

1.3 問題解決

1.3.1 問題1:絕對路徑的獲取

問題1 用下面的代碼能夠獲取程序的絕對路徑。github

String projectDir = 所在類名.class.getClass().getResource("/").getPath();
System.out.println(projectDir);

// 在eclipse中運行輸出結果示例
/E:/workspace_set/big_data_workspace/DemoTest/bin/

// 打成jar包運行的輸出結果示例
/E:/workspace_set/big_data_workspace/DemoTest

1.3.2 問題2:帶依賴jar包的打jar包與路徑問題

打包步驟簡述:Export ==> Java ==> Runnable Jar file ==>
在luanch configuration中選擇你的main方法所在的類,在Export destination中輸入類名,Library handling選擇第一項(extract required libraries into genetated jar)便可,以下圖所示。==> finish。web

2019-11-19_152049.png

注意事項:對於打成帶有第三方依賴包的jar包時,Library handling選擇第一項(將依賴的jar解壓出來變成class放進你生成的jar),如上圖。緣由:選擇第二項時,絕對路徑獲取的代碼輸出爲null。app

String projectDir = 所在類名.class.getClass().getResource("/").getPath();
System.out.println(projectDir);

// 當Library handling選擇第二項時,的輸出
null;

1.3.3 問題3:絕對路徑值傳遞給Log4j日誌框架,相關的配置

1 log4j.properties文件中的配置說明,在log4j.properties文件中,使用${系統變量名}來引用變量(絕對路徑),示例以下。框架

log4j.appender.file.File=${base.dir}mylog5.log

2 Java程序中的處理。eclipse

// 1 在logger私例化以前,執行下面的代碼
// 獲取絕對路徑
String projectDir = 所在類名.class.getClass().getResource("/").getPath();
// 將絕對路徑賦值給系統變量
System.setProperty("base.dir", projectDir);

// 2 Read the configuration file configFilename if it exists.
// 這裏至關於從新加載,讓絕對路徑的配置生效;
PropertyConfigurator.configure(projectDir + "log4j.properties");

// 存放絕對路徑的系統變量,被Log4j加載的測試
// 獲取FileAppender對象
FileAppender appender= (FileAppender) Logger.getRootLogger().getAppender("file");
// 輸出示例:/E:/workspace_set/big_data_workspace/DemoTest/bin/mylog5.log
System.out.println(appender.getFile());

// 3 實例化Logger;
Logger logger = Logger.getLogger(當前類名.class);

通過上述步驟,即完成了log4j的正常輸出。測試

1.4 其它問題彙總

1.4.1 問題1

下面是在使用過程當中遇到的問題的解釋。
現象:在eclipse中執行時,會沒有輸出日誌的文件。可是,打包出去(打包的話,按照本文的操做步驟去打jar包),不管是在程序所在的目錄下,仍是在其它的目錄下,執行這個jar包,都能正常的輸出日誌文件。
緣由:ui

// 獲取絕對路徑
String projectDir = 所在類名.class.getClass().getResource("/").getPath();
System.out.println(projectDir);

// 在eclipse中執行的輸出值
projectDir=/E:/workspace_set/big_data_workspace/DemoTest/bin/

// 打成jar包的輸出值
projectDir=/E:/workspace_set/big_data_workspace/DemoTest/

如上,/E:/workspace_set/big_data_workspace/DemoTest/bin/,這個路徑找不到,因此在eclipse中,日誌無法正常執行輸出。
因此說,這個是正常現象,不影響咱們打包出的jar正常的輸出日誌文件到指定目錄。
存放絕對路徑的系統變量,是會被Log4j加載,且生效了。測試代碼以下:lua

// 存放絕對路徑的系統變量,被Log4j加載的測試
// log4j.properties文件中的配置假設以下:
// log4j.appender.file.File=${base.dir}mylog5.log

// 測試代碼
String projectDir = TestLog2.class.getClass().getResource("/").getPath();
PropertyConfigurator.configure(projectDir + "log4j.properties");

//獲取FileAppender對象
FileAppender appender= (FileAppender) Logger.getRootLogger().getAppender("file");
System.out.println(appender.getFile());

// 輸出值結果示例:
/E:/workspace_set/big_data_workspace/DemoTest/bin/mylog5.log

1.4.2 問題2 文件讀取

問題描述:獲取的絕對路徑在eclipse中執行,因爲獲取的路徑中帶有bin這個字段,對於位於src目錄下的文件讀取有影響嗎?
問題答案:沒有。使用獲取的絕對路徑+文件名,即爲src目錄下文件的絕對路徑。這個你們能夠作個小實驗。這裏就不展開了。

1.5 本文相關的代碼地址

https://github.com/chuzhixing...

2 參考文獻

https://blog.csdn.net/qq_2180... (eclipse 導出可運行jar包時三種Library handling的區別 - 小藍的博客 - CSDN博客)

相關文章
相關標籤/搜索