天天看點

獲得執行jar的運作路徑-使用java.class.path 和 codesource的location

題記

上一篇使用了一個叫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包執行的路徑!而且可以識别中文!

(3) 過于System.getProperty的用法參見http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html

參考代碼如下中的getPath方法。

方法二:『力薦』

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包的完整路徑。很容易可以得出程式運作的目錄!具體程式如下:如getPath2()所示。

package system.property.java_class.path;

import java.io.File;

import java.io.UnsupportedEncodingException;

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",用"/"(linux,unix)分割不行 

            //下面的語句輸出是-1,應該改為lastIndexOf("\")或者lastIndexOf(File.separator) 

//          System.out.println("getPath2:"+filePath.lastIndexOf("/")); 

            filePath = filePath.substring(0, filePath.lastIndexOf(File.separator) + 1); 

            //File.separator:Character that separates components of a file path. This is "/" on UNIX and "" on Windows.

        }

        System.out.println(filePath);

        return filePath;

    }

    public static String getPath2(){

        //所有url都以file:/開始,以"/"作為分隔符末尾 并且以/作為末尾結束符

        URL url=MyPath.class.getProtectionDomain().getCodeSource().getLocation();

        String filePath=null;

        try {

            filePath=URLDecoder.decode(url.getPath(),"utf-8");//轉化成utf-8編碼

        } catch (UnsupportedEncodingException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        if(filePath.endsWith(".jar")){//可執行jar包運作的結果包含".jar"

            // 截取路徑中的jar包名 

            filePath=filePath.substring(0, filePath.lastIndexOf("/")+1);

        File file=new File(filePath);

        filePath = file.getAbsolutePath();//得到windows下的正确路徑 

        System.out.println(filePath);

    public static void main(String[] args){

        MyPath.getPath();

        MyPath.getPath2();

}

總結:

在實際使用過程中,隻需要使用上述兩種方法中的一種即可!!

引用參考:blog.csdn.net/whuslei

原址:http://blog.sina.com.cn/s/blog_605f5b4f01010h6g.html