獲得執行jar的執行路徑
題記
上一篇使用了一個叫fat-jar的外掛來製作jar包,確實很方便。但我們更容易遇到另一個更為棘手的問題!如何得到jar包的執行路徑?
如果沒有這個路徑,我們讀取檔案可能找不到路徑,寫檔案可能寫到別的目錄裡了!
而且,除錯程式碼時我們需要eclipse裡的命令列裡執行,而不需要打包;最終釋出時我們需要打成jar包!所以,這部分程式碼應該要支援以上兩種形式。
一般執行jar包有下面兩種方式:
1、cd 到包含該jar包的目錄裡,執行命令
java -jar Demorun_fat.jar
2、直接加入絕對路徑(比如把jar包直接拖入cmd視窗,就可以得到jar包的路徑了)並執行命令
所以,如果直接取相對路徑就會得到兩個結果,前者會是“E:\workspace4svn\Demorun\”,後者是"當前目錄,如C:\"。
解決辦法
下面以一個jar包和一個data/in.txt為例來說明下面兩種方法:
方法一:
System.getProperty("java.class.path")在eclipse裡執行(不打包)的結果是: “E:\workspace4svn\Demorun\bin;E:\workspace4svn\Hello\Hello_fat.jar” (注意:Hello_fat.jar不是可執行的jar,是從外部引入的包)
在cmd裡執行jar包的結果是:“E:\workspace4svn\Demorun\Demorun_fat.jar”
[小結]
(1) 這種方法在eclipse中執行結果的意思是"Path used to find directories and JAR archives containing class files.",也就是結果包括了可執行.class檔案的路徑以及引入的jar包路徑。
(2) 打包成jar包後,結果是jar包執行的路徑!而且可以識別中文!
參考程式碼如下:
import java.io.File; import java.net.URL; import java.net.URLDecoder; public class MyPath { public static String getPath(){ String filePath = System.getProperty("java.class.path"); String pathSplit = System.getProperty("path.separator");//windows下是";",linux下是":" if(filePath.contains(pathSplit)){ filePath = filePath.substring(0,filePath.indexOf(pathSplit)); }else if (filePath.endsWith(".jar")) {//擷取路徑中的jar包名,可執行jar包執行的結果裡包含".jar" //此時的路徑是"E:\workspace\Demorun\Demorun_fat.jar",用"/"分割不行 //下面的語句輸出是-1,應該改為lastIndexOf("\\")或者lastIndexOf(File.separator) // System.out.println("getPath2:"+filePath.lastIndexOf("/")); filePath = filePath.substring(0, filePath.lastIndexOf(File.separator) + 1); } return filePath; } }
方法二:『力薦』 ClassName.class.getProtectionDomain().getCodeSource().getLocation().getPath()
在eclipse裡執行(不打包)的結果是: “/E:/workspace/Demorun/bin/”
在cmd裡執行jar包的結果是:“/E:/workspace/Demorun/Demorun_fat.jar”
如果不加.getPath,則結果是"file:/E:/workspace/Demorun/bin/"和"file:/E:/workspace/Demorun/Demorun_fat.jar",也就是說結果前面多了個"file:"
[小結]
(1) 這種方法不支援中文,需要轉化下。
(2) 特別注意結果中的"斜線",方法一是windows中路徑的正確表示,用"\"分割;方法二里是用"/"來分割,不是正確的路徑!所以需要用file.getAbsolutePath();轉化!
(3) 結果差異不大,在eclipse中的結果是.MainClass所在目錄,而jar包執行的結果是jar包的完整路徑。很容易可以得出程式執行的目錄!具體程式如下:
import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
public class MyPath {
public static String getPath() {
URL url = MyPath.class.getProtectionDomain().getCodeSource().getLocation();
String filePath = null;
try {
filePath = URLDecoder.decode(url.getPath(), "utf-8");// 轉化為utf-8編碼
} catch (Exception e) {
e.printStackTrace();
}
if (filePath.endsWith(".jar")) {// 可執行jar包執行的結果裡包含".jar"
// 擷取路徑中的jar包名
filePath = filePath.substring(0, filePath.lastIndexOf("/") + 1);
}
File file = new File(filePath);
// /If this abstract pathname is already absolute, then the pathname
// string is simply returned as if by the getPath method. If this
// abstract pathname is the empty abstract pathname then the pathname
// string of the current user directory, which is named by the system
// property user.dir, is returned.
filePath = file.getAbsolutePath();//得到windows下的正確路徑
return filePath;
}
}
總結:
在實際使用過程中,只需要使用上述兩種方法中的一種即可!!行文比較倉促,如有錯誤,歡迎指正!轉載請宣告出處:blog.csdn.net/whuslei
參考:
(全文完)