java 读取JAR文件外的属性文件

db2dz4w8  于 2023-08-02  发布在  Java
关注(0)|答案(9)|浏览(117)

我有一个JAR文件,我所有的代码都存档在那里以便运行。我必须访问一个属性文件,该文件需要在每次运行之前进行更改/编辑。我想将属性文件保存在JAR文件所在的目录中。是否有任何方法可以告诉Java从该目录中获取属性文件?
注意:我不想将属性文件保存在主目录中,也不想在命令行参数中传递属性文件的路径。

8iwquhpp

8iwquhpp1#

因此,您希望将与main/runnable jar位于同一文件夹中的.properties文件视为一个文件,而不是main/runnable jar的资源。在这种情况下,我自己的解决方案如下:
第一件事你的程序文件结构应该是这样的(假设你的主程序是main.jar,它的主属性文件是main.properties):

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

字符串
有了这个架构,你可以main.properties在main.jar运行之前或运行时(取决于程序的当前状态)使用任何文本编辑器修改www.example.com文件中的任何属性,因为它只是一个基于文本的文件。例如,您的main.properties文件可能包含:

app.version=1.0.0.0
app.name=Hello


所以,当你从root/base文件夹运行主程序时,通常你会这样运行它:

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
 */

import java.util.Properties;

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();
}

kd3sttzy

kd3sttzy2#

我用另一种方法做了这件事。

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文件路径。
1.获取该文件的父文件夹。
1.在InputStreamPath中将该路径与您的属性文件名一起使用。

tyky79it

tyky79it3#

从jar文件访问文件目录中的文件总是有问题。在jar文件中提供类路径是非常有限的。相反,尝试使用bat文件或sh文件来启动程序。通过这种方式,您可以任意指定类路径,引用系统上任何位置的任何文件夹。
也可以看看我对这个问题的回答:
为包含sqlite的java项目制作.exe文件

3vpjnl9f

3vpjnl9f4#

我有一个类似的案例:希望我的*.jar文件访问一个文件在一个目录下说*.jar文件.也可以参考THIS ANSWER
我的文件结构是:

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

字符串
我可以将一个文件(比如some.txt)加载到*.jar文件中的InputStream中,如下所示:

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执行任何操作

ygya80vv

ygya80vv5#

如果你在这里提到.getPath(),那么它将返回Jar的路径,我猜你需要它的父文件来引用与jar一起放置的所有其他配置文件。此代码适用于Windows。在主类中添加代码。

File jarDir = new File(MyAppName.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String jarDirpath = jarDir.getParent();

System.out.println(jarDirpath);

字符串

55ooxyrt

55ooxyrt6#

这对我很有效从current directory加载属性文件。

注意事项:方法Properties#loaduses ISO-8859-1 encoding

Properties properties = new Properties();
properties.load(new FileReader(new File(".").getCanonicalPath() + File.separator + "java.properties"));
properties.forEach((k, v) -> {
            System.out.println(k + " : " + v);
        });

字符串
确保java.properties位于current directory。你可以写一个小的启动脚本,切换到之前的正确目录,像

#! /bin/bash
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 
cd $scriptdir
java -jar MyExecutable.jar
cd -


在您的项目中,只需将java.properties文件放在项目根目录下,以便使此代码也能在IDE中工作。

vpfxa7rd

vpfxa7rd7#

我有一个通过类路径或外部配置log4j2.properties来执行这两种操作的示例

package org.mmartin.app1;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.LogManager;

public class App1 {
    private static Logger logger=null; 
    private static final String LOG_PROPERTIES_FILE = "config/log4j2.properties";
    private static final String  CONFIG_PROPERTIES_FILE = "config/config.properties";

    private Properties properties= new Properties();

    public App1() {
        System.out.println("--Logger intialized with classpath properties file--");
        intializeLogger1();
        testLogging();
        System.out.println("--Logger intialized with external file--");
        intializeLogger2();
        testLogging();
    }



    public void readProperties()  {
        InputStream input = null;
        try {
            input = new FileInputStream(CONFIG_PROPERTIES_FILE);
            this.properties.load(input);
        } catch (IOException e) {
            logger.error("Unable to read the config.properties file.",e);
            System.exit(1);
        }
    }

    public void printProperties() {
        this.properties.list(System.out);
    }

    public void testLogging() {
        logger.debug("This is a debug message");
        logger.info("This is an info message");
        logger.warn("This is a warn message");
        logger.error("This is an error message");
        logger.fatal("This is a fatal message");
        logger.info("Logger's name: "+logger.getName());
    }

    private void intializeLogger1() {
        logger = LogManager.getLogger(App1.class);
    }
    private void intializeLogger2() {
        LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
        File file = new File(LOG_PROPERTIES_FILE);
        // this will force a reconfiguration
        context.setConfigLocation(file.toURI());
        logger = context.getLogger(App1.class.getName());
    }

    public static void main(String[] args) {
        App1 app1 = new App1();
        app1.readProperties();
        app1.printProperties();
    }
}

--Logger intialized with classpath properties file--
[DEBUG] 2018-08-27 10:35:14.510 [main] App1 - This is a debug message
[INFO ] 2018-08-27 10:35:14.513 [main] App1 - This is an info message
[WARN ] 2018-08-27 10:35:14.513 [main] App1 - This is a warn message
[ERROR] 2018-08-27 10:35:14.513 [main] App1 - This is an error message
[FATAL] 2018-08-27 10:35:14.513 [main] App1 - This is a fatal message
[INFO ] 2018-08-27 10:35:14.514 [main] App1 - Logger's name: org.mmartin.app1.App1
--Logger intialized with external file--
[DEBUG] 2018-08-27 10:35:14.524 [main] App1 - This is a debug message
[INFO ] 2018-08-27 10:35:14.525 [main] App1 - This is an info message
[WARN ] 2018-08-27 10:35:14.525 [main] App1 - This is a warn message
[ERROR] 2018-08-27 10:35:14.525 [main] App1 - This is an error message
[FATAL] 2018-08-27 10:35:14.525 [main] App1 - This is a fatal message
[INFO ] 2018-08-27 10:35:14.525 [main] App1 - Logger's name: org.mmartin.app1.App1
-- listing properties --
dbpassword=password
database=localhost
dbuser=user

字符串

h5qlskok

h5qlskok8#

File parentFile = new File(".");
String parentPath = file.getCanonicalPath();
File resourceFile = new File(parentPath+File.seperator+"<your config file>");

字符串

rkttyhzu

rkttyhzu9#

一种方法是使用META-INF/MANIFEST.MF文件中的以下条目在JAR的类路径中添加当前目录:

Class-Path: .

字符串
然后下面的代码加载“system.properties“文件将无缝工作:

ResourceBundle systemPropertiesBundle = ResourceBundle.getBundle("system");

相关问题