2012-01-08 76 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