1. 程式人生 > >獲得執行jar的執行路徑

獲得執行jar的執行路徑

題記

上一篇使用了一個叫fat-jar的外掛來製作jar包,確實很方便。但我們更容易遇到另一個更為棘手的問題!如何得到jar包的執行路徑?

如果沒有這個路徑,我們讀取檔案可能找不到路徑,寫檔案可能寫到別的目錄裡了!

而且,除錯程式碼時我們需要eclipse裡的命令列裡執行,而不需要打包;最終釋出時我們需要打成jar包!所以,這部分程式碼應該要支援以上兩種形式。

一般執行jar包有下面兩種方式:

1、cd 到包含該jar包的目錄裡,執行命令

cd E:\workspace4svn\Demorun\
java -jar  Demorun_fat.jar

2、直接加入絕對路徑(比如把jar包直接拖入cmd視窗,就可以得到jar包的路徑了)並執行命令

java -jar  E:\workspace4svn\Demorun\Demorun_fat.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

參考:

(全文完)