2012-01-08 60 views
86

我有一個JAR文件,我的所有代碼都存檔以供運行。我必須在每次運行之前訪問需要更改/編輯的屬性文件。我想將屬性文件保存在JAR文件所在的同一目錄中。無論如何告訴Java從該目錄中獲取屬性文件?閱讀JAR文件之外的屬性文件

注意:我不想將屬性文件保存在主目錄中或在命令行參數中傳遞屬性文件的路徑。

+0

看到[這個答案](http://stackoverflow.com/a/5052359/418556) - *「而不是將'默認'文件存儲在Jar中。如果它被更改,存儲在另一個地方修改過的文件。一個常見的地方是'user.home'的子目錄。檢查文件時,首先檢查文件系統上是否存在修改過的文件,如果不存在,請加載默認文件。「* **順便說一句** *」我不想..「想要的不是什麼有效而且實用的東西。將應用程序設置存儲在應用程序目錄中是非常不鼓勵Oracle&MS(&可能是其他人)。 – 2012-01-08 05:05:58

+2

我需要將屬性文件保存在jar目錄中的原因是當整個目錄(包括jar和屬性)被複制到另一臺機器並運行時,最好將它們放在一起 – SoulMan 2012-01-08 08:47:13

+0

如果我強制用戶傳遞屬性文件路徑,那麼每次運行批處理時都需要更改它文件來自另一臺機器 – SoulMan 2012-01-08 08:48:46

回答

112

所以,你要正確對待在同一文件夾作爲主/運行的JAR的文件,而不是作爲對資源的.properties文件主/可運行的jar。在這種情況下,我自己的解決方案如下:

第一件事,第一:你的程序文件的架構應該是這樣的(假設你的主程序和的main.jar其主要屬性文件main.properties):

./ - the root of your program 
|__ main.jar 
|__ main.properties 

通過這種架構,您可以在運行main.jar之前或之後使用任何文本編輯器修改main.properties文件中的任何屬性(取決於程序的當前狀態),因爲它只是基於文本的文件。例如,您的main.properties文件可能包含:

app.version=1.0.0.0 
app.name=Hello 

所以,當你從它的根/基礎文件夾中運行主程序,通常你會遇到這樣的:

java -jar ./main.jar 

,或者直線距離:

java -jar main.jar 

在你main.jar文件,你需要爲你的main.properties文件中找到的每個屬性的幾個實用方法;讓說app.version屬性將有getAppVersion()方法如下:

/** 
* Gets the app.version property value from 
* the ./main.properties file of the base folder 
* 
* @return app.version string 
* @throws IOException 
*/ 
public static String getAppVersion() throws IOException{ 

    String versionString = null; 

    //to load application's properties, we use this class 
    Properties mainProperties = new Properties(); 

    FileInputStream file; 

    //the base folder is ./, the root of the main.properties file 
    String path = "./main.properties"; 

    //load the file handle for main.properties 
    file = new FileInputStream(path); 

    //load all the properties from this file 
    mainProperties.load(file); 

    //we have loaded the properties, so close the file handle 
    file.close(); 

    //retrieve the property we are intrested, the app.version 
    versionString = mainProperties.getProperty("app.version"); 

    return versionString; 
} 

在需要的app.version價值的主要程序的任何部分,我們調用它的方法如下:

String version = null; 
try{ 
    version = getAppVersion(); 
} 
catch (IOException ioe){ 
    ioe.printStackTrace(); 
} 
+7

這個解決方案有效,感謝您理解確切的需求和詳細的代碼。我確認屬性文件不在jar文件中,但仍然可以從同一個導向器訪問文件y jar文件所在的位置。這樣就不需要絕對路徑硬代碼。現在,jar和屬性文件都可以複製到任何目錄並獨立運行。 – SoulMan 2012-01-09 07:50:06

+1

如果您執行外部命令,例如{{java -jar build/main.jar}},則不會找到該文件。你有沒有解決這個問題,@eee? – Darian 2015-07-09 03:56:33

+0

@Darian這裏沒有什麼可以解決的;它只能在jar和屬性文件必須位於與我在文件組織體系結構中描述過的內容相同的'。/'根文件夾(相同目錄級別)的情況下設計。 (根據原始海報的要求) – ecle 2015-07-09 04:57:58

0

從jar文件訪問文件目錄中的文件總是有問題。在jar文件中提供類路徑非常有限。請嘗試使用bat文件或sh文件來啓動程序。通過這種方式,您可以隨意指定您的類路徑,並引用系統上任何位置的任何文件夾。

還檢查我的回答這個問題:

making .exe file for java project containing sqlite

27

我做到了通過另一種方式。

Properties prop = new Properties(); 
    try { 

     File jarPath=new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath()); 
     String propertiesPath=jarPath.getParentFile().getAbsolutePath(); 
     System.out.println(" propertiesPath-"+propertiesPath); 
     prop.load(new FileInputStream(propertiesPath+"/importer.properties")); 
    } catch (IOException e1) { 
     e1.printStackTrace(); 
    } 
  1. 獲取Jar文件路徑。
  2. 獲取該文件的父文件夾。
  3. 在您的屬性文件名中使用InputStreamPath中的路徑。
+0

我不得不放棄getParentFile()部分,所以我使用:String propertiesPath = jarPath.getAbsolutePath();但這一切都取決於文件的位置 – MobileMon 2014-02-25 13:07:43

+2

只需替換「jarPath.getParentFile()。getAbsolutePath();」到「jarPath.getParent()」。那麼就像魅力一樣。 – StackAddict 2015-01-07 10:22:05

+0

我的情況同樣是問題,但我有春季基地項目。如何告訴spring文件在jar文件旁邊?任何想法 – Mubasher 2017-03-10 13:00:06

0

我有一個類似的情況:想讓我的*.jar文件訪問上述*.jar文件旁邊目錄中的文件。同樣參考THIS ANSWER

我的文件結構是:

./ - the root of your program 
|__ *.jar 
|__ dir-next-to-jar/some.txt 

我能到一個文件中(比如,some.txt)加載到InputStream中*.jar文件中有以下內容:

InputStream stream = null; 
    try{ 
     stream = ThisClassName.class.getClass().getResourceAsStream("/dir-next-to-jar/some.txt"); 
    } 
    catch(Exception e) { 
     System.out.print("error file to stream: "); 
     System.out.println(e.getMessage()); 
    } 

然後爲所欲爲你將與​​stream