用Java读取属性文件


105

我有以下代码尝试读取属性文件:

Properties prop = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();           
InputStream stream = loader.getResourceAsStream("myProp.properties");
prop.load(stream);

我在最后一行有一个例外。特别:

Exception in thread "main" java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:418)
at java.util.Properties.load0(Properties.java:337)
at java.util.Properties.load(Properties.java:325)
at Assignment1.BaseStation.readPropertyFile(BaseStation.java:46)
at Assignment1.BaseStation.main(BaseStation.java:87)

谢谢,尼科斯

Answers:


89

根据您的异常,该InputStream值为null,这意味着类加载器未找到您的属性文件。我猜myProp.properties在项目的根目录中,如果是这种情况,则需要前面的斜杠:

InputStream stream = loader.getResourceAsStream("/myProp.properties");

我的文件层次结构是:src-> myPackage-> myClass.java和myProp.properties。我按照您的建议做了,但仍然会引发相同的异常
nikos 2011年

getResourceAsStream在类路径上搜索文件。如果您的属性文件位于的包目录中myPackage,请/myPackage/myProp.properties用作路径。
Jesper

2
@Mark Elliot如果我有一个conf软件包来存储所有配置文件,并且我的文件层次结构是:myproject ->src, conf, test我该如何通过添加前面的斜杠来加载属性?
罗杰·雷

54


您可以在此页面上找到信息:http :
//www.mkyong.com/java/java-properties-file-examples/

Properties prop = new Properties();
try {
    //load a properties file from class path, inside static method
    prop.load(App.class.getClassLoader().getResourceAsStream("config.properties"));

    //get the property value and print it out
    System.out.println(prop.getProperty("database"));
    System.out.println(prop.getProperty("dbuser"));
    System.out.println(prop.getProperty("dbpassword"));

} 
catch (IOException ex) {
    ex.printStackTrace();
}

3
根据文档,别忘了关闭Readerin prop.load(reader)The specified stream remains open after this method returns
Evandro Silva

25

您可以使用ResourceBundle类读取属性文件。

ResourceBundle rb = ResourceBundle.getBundle("myProp.properties");

1
ResourceBundle rb = ResourceBundle.getBundle(“ myProp”);
mcolak

2
建议 i18n使用此方法。
另一个

15
Properties prop = new Properties();

try {
    prop.load(new FileInputStream("conf/filename.properties"));
} catch (IOException e) {
    e.printStackTrace();
}

conf/filename.properties 基于项目根目录


7

你不能用这个关键字,例如-

props.load(this.getClass().getResourceAsStream("myProps.properties"));

在静态环境中。

最好的办法是掌握应用程序上下文,例如-

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/META-INF/spring/app-context.xml");

然后您可以从类路径加载资源文件-

//load a properties file from class path, inside static method
        prop.load(context.getClassLoader().getResourceAsStream("config.properties"));

这对于静态和非静态上下文均适用,最好的部分是此属性文件可以位于应用程序的类路径中包含的任何程序包/文件夹中。


4
ApplicationContext仅在Spring应用程序中可用
joro

6

您的文件应该可以com/example/foo/myProps.properties在classpath中使用。然后将其加载为:

props.load(this.getClass().getResourceAsStream("myProps.properties"));

4

如果您的config.properties不在src / main / resource目录中,而在项目的根目录中,那么您需要执行以下操作:

Properties prop = new Properties();          
File configFile = new File(myProp.properties);
InputStream stream = new FileInputStream(configFile);
prop.load(stream);

3

确保文件名正确,并且文件实际上在类路径中。 getResourceAsStream()如果不是这种情况,它将返回null,这将导致最后一行引发异常。

如果myProp.properties在项目的根目录中,请/myProp.properties改用。


我的文件层次结构是:src-> myPackage-> myClass.java和myProp.properties。我按照您的建议做了,但仍然会抛出相同的异常
nikos 2011年

由于属性文件不在项目的根目录下,因此不需要斜杠。
mort

首先,我得到的异常没有前导斜线。它仍然无法正常工作。
nikos 2011年

3

您可以使用java.io.InputStream读取文件,如下所示:

InputStream inputStream = getClass().getClassLoader().getResourceAsStream(myProps.properties); 

如何在Java中将InputStream转换为File?我想使用File API读取.properties文件

3

给定上下文loader.getResourceAsStream("myPackage/myProp.properties")应使用。

领导'/'不起作用ClassLoader.getResourceAsStream(String)方法。

或者,您可以使用Class.getResourceAsStream(String)方法,该方法'/'用于确定路径是绝对路径还是相对于类位置的路径。

例子:

myClass.class.getResourceAsStream("myProp.properties")
myClass.class.getResourceAsStream("/myPackage/myProp.properties")

2

如果您的属性文件路径和Java类路径相同,则应该这样做。

例如:

src / myPackage / MyClass.java

src / myPackage / MyFile.properties

Properties prop = new Properties();
InputStream stream = MyClass.class.getResourceAsStream("MyFile.properties");
prop.load(stream);

2

当前的答案都没有显示InputStream关闭状态(这将泄漏文件描述符),和/或不处理.getResourceAsStream()在找不到资源时返回null的情况(这将导致NullPointerException出现混乱的消息"inStream parameter is null")。您需要以下内容:

String propertiesFilename = "server.properties";
Properties prop = new Properties();
try (var inputStream = getClass().getClassLoader().getResourceAsStream(propertiesFilename)) {
    if (inputStream == null) {
        throw new FileNotFoundException(propertiesFilename);
    }
    prop.load(inputStream);
} catch (IOException e) {
    throw new RuntimeException(
                "Could not read " + propertiesFilename + " resource file: " + e);
}

1

对于按原始顺序读取属性文件:

    File file = new File("../config/edc.properties");
    PropertiesConfiguration config = new PropertiesConfiguration();
    PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config);
    layout.load(new InputStreamReader(new FileInputStream(file)));

    for(Object propKey : layout.getKeys()){
        PropertiesConfiguration propval =  layout.getConfiguration();
        String value = propval.getProperty((String) propKey).toString();
        out.print("Current Key:" + propkey + "Current Value:" + propval + "<br>");
    }

1

这里有许多答案描述了危险的方法,在这些方法中它们实例化文件输入流,但未获得对输入流的引用,以便稍后关闭该流。这导致悬挂的输入流和内存泄漏。加载属性的正确方法应类似于以下内容:

    Properties prop = new Properties();
    try(InputStream fis = new FileInputStream("myProp.properties")) {
        prop.load(fis);
    }
    catch(Exception e) {
        System.out.println("Unable to find the specified properties file");
        e.printStackTrace();
        return;
    }

注意try-with-resources块中文件输入流的实例化。由于a FileInputStream是可自动关闭的,因此try-with-resources在退出该块后它将自动关闭。如果要使用简单的try块,则必须fis.close();finally块中使用显式关闭它。


0

我看到这个问题是一个古老的问题。如果将来有人偶然发现这个问题,我认为这是一种简单的方法。将属性文件保存在项目文件夹中。

        FileReader reader = new FileReader("Config.properties");

        Properties prop = new Properties();
        prop.load(reader);

-2

指定从src开始的路径,如下所示:

src/main/resources/myprop.proper
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.