如何使用Java属性文件?


219

我有要配置为Java属性文件的键/值对的列表,以后再加载和迭代。

问题:

  • 我是否需要将文件存储在与将要加载它们的类相同的程序包中,或者应该在任何特定位置放置文件?
  • 该文件是否需要以任何特定的扩展名结尾还是.txt可以的?
  • 如何在代码中加载文件
  • 我如何遍历其中的值?

Answers:


245

您可以将InputStream传递给Property,因此您的文件几乎可以在任何地方,并且可以调用任何东西。

Properties properties = new Properties();
try {
  properties.load(new FileInputStream("path/filename"));
} catch (IOException e) {
  ...
}

迭代为:

for(String key : properties.stringPropertyNames()) {
  String value = properties.getProperty(key);
  System.out.println(key + " => " + value);
}

当属性文件中不存在该键时,返回什么值?
Mitaksh Gupta'2

2
@MitakshGupta如果在文件或默认属性列表中找不到具有您传递的名称的属性,则它将返回null。参见Javadoc
drigoangelo 2014年

3
请问这个比较properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); 是,getResourceAsStreamFileInputStream?利弊?
Thufir 2015年

80
  • 可以将文件存储在任意位置。如果要将其保留在jar文件中,则需要使用Class.getResourceAsStream()ClassLoader.getResourceAsStream()访问它。如果在文件系统上,则稍微容易一些。

  • 任何扩展都可以,尽管.properties在我的经验中更常见

  • 使用加载该文件Properties.load,通过在一个InputStream或一个StreamReader,如果你使用的是Java 6(如果您正在使用Java 6,我可能会使用UTF-8和Reader而不是默认的ISO-8859-1编码流。 )

  • 像遍历法线HashtableProperties派生自)一样遍历它,例如使用keySet()。或者,您可以使用由返回的枚举propertyNames()


1
谢谢乔恩,接下来我知道我会在joda上查找内容,您也会回答。
Flame

27

如果将属性文件与Foo类放在同一包中,则可以轻松地将其加载

new Properties().load(Foo.class.getResourceAsStream("file.properties"))

鉴于属性扩展了Hashtable,您可以以与在Hashtable中相同的方式遍历值。

如果使用* .properties扩展名,则可以获得编辑器支持,例如Eclipse具有属性文件编辑器。


5
可以执行此操作-但我不喜欢将属性文件存储在同一包中。最终,属性文件散布在应用程序的各处。我宁愿将所有属性文件存储在应用程序的根目录中,并将其作为“ class.getResourceAsStream(“ \ file.properties”)“或其他已知位置加载。
Nate

内特,是的。但是,在某些情况下,部署位置未知(例如,特定组件的所有内容都捆绑在某个存档中)。在这种情况下,说出“与那个班级在一起,无论那个班级最终到达何处”都是很方便的。另外,为避免将文件散布开,可以将单个配置包用于所有属性文件。
Fabian Steeg

1
Fabian,这两种情况都符合我的意见-它基于类路径-而不是文件系统。
Nate

2
对于任何试图使Nate的示例生效的人,应将反斜杠替换为正斜杠。因此,在这种情况下:'class.getResourceAsStream(“ / file.properties”)'
hash_collision

12

有多种创建和读取properties文件的方法:

  1. 将文件存储在相同的程序包中。
  2. 推荐.properties扩展名,但是您可以选择自己的扩展名。
  3. 使用论文位于类java.util包=> ,,Properties 类。ListResourceBundleResourceBundle
  4. 要读取属性,请使用迭代器或枚举器或Propertiesor java.lang.System类的直接方法。

ResourceBundle 类:

 ResourceBundle rb = ResourceBundle.getBundle("prop"); // prop.properties
 System.out.println(rb.getString("key"));

Properties 类:

Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));

嗨,AVD,为什么我们.properties只需要扩展?.txt扩展有什么问题?请帮助我。
atish shimpi 2014年

@atishshimpi使用“属性”类型时不是必需的,但对于ResourceBundle是必需的-请阅读doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost 2014年

5

这将加载属性文件:

Properties prop = new Properties();
InputStream stream = ...; //the stream to the file
try {
  prop.load(stream);
} finally {
  stream.close();
}

我曾经将.properties文件放在我拥有所有配置文件的目录中,没有将它与访问它的类放在一起,但是这里没有任何限制。

的名字...为了冗长起见,我使用.properties,如果您不愿意的话,我不认为您应该将其命名为.properties。


但是,属性文件的某些“扩展名”采用.properties扩展名-例如,在I18N中使用的ResourceBundle。
Nate

5

例:

Properties pro = new Properties();
FileInputStream in = new FileInputStream("D:/prop/prop.properties");
pro.load(in);
String temp1[];
String temp2[];
// getting values from property file
String username = pro.getProperty("usernamev3");//key value in prop file 
String password = pro.getProperty("passwordv3");//eg. username="zub"
String delimiter = ",";                         //password="abc"
temp1=username.split(delimiter);
temp2=password.split(delimiter);

如果您有3个属性文件怎么办?
安吉丽娜2014年

4

财产已成为遗产。首选项类优于属性。

偏好数据的分层集合中的节点。此类允许应用程序存储和检索用户和系统偏好设置以及配置数据。此数据永久存储在与实现相关的后备存储中。典型的实现包括平面文件,特定于操作系统的注册表,目录服务器和SQL数据库。此类的用户不必关心后备存储的详细信息。

与基于字符串的键值对的属性不同,Preferences该类具有几种用于获取原始数据并将其放入Preferences数据存储中的方法。我们只能使用以下类型的数据:

  1. 布尔值
  2. 浮动
  3. 整型
  4. 字节数组

要加载属性文件,可以提供绝对路径,也可以使用getResourceAsStream()classpath中是否存在属性文件的方式使用。

package com.mypack.test;

import java.io.*;
import java.util.*;
import java.util.prefs.Preferences;

public class PreferencesExample {

    public static void main(String args[]) throws FileNotFoundException {
        Preferences ps = Preferences.userNodeForPackage(PreferencesExample.class);
        // Load file object
        File fileObj = new File("d:\\data.xml");
        try {
            FileInputStream fis = new FileInputStream(fileObj);
            ps.importPreferences(fis);
            System.out.println("Prefereces:"+ps);
            System.out.println("Get property1:"+ps.getInt("property1",10));

        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}

xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
<preferences EXTERNAL_XML_VERSION="1.0">
<root type="user">
<map />
<node name="com">
  <map />
  <node name="mypack">
    <map />
    <node name="test">
      <map>
        <entry key="property1" value="80" />
        <entry key="property2" value="Red" />
      </map>
    </node>
  </node>
</node>
</root>
</preferences>

看看这篇关于偏好存储内部的文章


3

为了:

  1. 您可以将文件存储在几乎任何地方。
  2. 无需扩展。
  3. 蒙特克里斯托(Montecristo)已说明了如何加载此内容。那应该工作正常。
  4. propertyNames()为您提供枚举以进行迭代。

2. no extension is necessary,能否请您提供此声明的任何参考。我对此感到困惑。
atish shimpi 2014年

请注意,您可以通过输入流加载属性。因此,这些属性不知道该输入流来自何处(文件或套接字?),因此无法强制执行命名标准
Brian Agnew 2014年

3

默认情况下,Java在应用程序的工作目录中打开它(此行为实际上取决于所使用的操作系统)。要加载文件,请执行以下操作:

Properties props = new java.util.Properties();
FileInputStream fis new FileInputStream("myfile.txt");
props.load(fis)

这样,任何文件扩展名都可以用于属性文件。此外,文件也可以存储在任何地方,只要您可以使用即可FileInputStream

与此相关的是,如果您使用的是现代框架,则该框架可能会提供其他打开属性文件的方法。例如,Spring提供了ClassPathResource一个从JAR文件内部使用包名称加载属性文件的功能。

至于遍历属性,一旦加载属性,它们就会存储在java.util.Properties提供propertyNames()方法的对象中。


3

读取属性文件并将其内容加载到 Properties

String filename = "sample.properties";
Properties properties = new Properties();

input = this.getClass().getClassLoader().getResourceAsStream(filename);
properties.load(input);

以下是迭代一个有效的方法 Properties

    for (Entry<Object, Object> entry : properties.entrySet()) {

        System.out.println(entry.getKey() + " => " + entry.getValue());
    }

3

Java 8中获取所有属性

public static Map<String, String> readPropertiesFile(String location) throws Exception {

    Map<String, String> properties = new HashMap<>();

    Properties props = new Properties();
    props.load(new FileInputStream(new File(location)));

    props.forEach((key, value) -> {
        properties.put(key.toString(), value.toString());
    });

    return properties;
}

2

1)将属性文件放在类路径中很好,但是您可以将其放在项目中的任何位置。

下面是如何从类路径加载属性文件并读取所有属性的方法。

Properties prop = new Properties();
InputStream input = null;

try {

    String filename = "path to property file";
    input = getClass().getClassLoader().getResourceAsStream(filename);
    if (input == null) {
        System.out.println("Sorry, unable to find " + filename);
        return;
    }

    prop.load(input);

    Enumeration<?> e = prop.propertyNames();
    while (e.hasMoreElements()) {
        String key = (String) e.nextElement();
        String value = prop.getProperty(key);
        System.out.println("Key : " + key + ", Value : " + value);
    }

} catch (IOException ex) {
    ex.printStackTrace();
} finally {
    if (input != null) {
        try {
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2)属性文件的扩展名为.properties


1

这是迭代属性的另一种方法:

Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) { 
    String key = (String) eProps.nextElement(); 
    String value = properties.getProperty(key); 
    System.out.println(key + " => " + value); 
}

2
真对不起 我查看了Zed的答案中的代码,它工作得很好……我当时不知道我的想法……实际上,我认为他的解决方案比我的
要好

1

去年,我已经撰写了有关此属性框架的文章。它将提供多种方式来加载属性,并对其进行强类型化。

看看http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped将为开发人员提供强类型化的属性。易于集成到现有项目中。由大量针对房地产类型的系列处理。通过属性IO实现提供单行初始化属性的功能。使开发人员能够创建自己的属性类型和属性io。Web演示也可用,屏幕截图如上所示。如果选择使用Web前端,还可以使用标准实现来管理属性。

项目网页上提供了完整的文档,教程,javadoc,常见问题解答等。


0

这里准备好静态课

import java.io.*;
import java.util.Properties;
public class Settings {
    public static String Get(String name,String defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return props.getProperty(name);
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static Integer Get(String name,Integer defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return Integer.valueOf(props.getProperty(name));
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static Boolean Get(String name,Boolean defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return Boolean.valueOf(props.getProperty(name));
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static void Set(String name, String value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer, Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
    public static void Set(String name, Integer value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer,Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
    public static void Set(String name, Boolean value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer,Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
}

这里示例:

Settings.Set("valueName1","value");
String val1=Settings.Get("valueName1","value");
Settings.Set("valueName2",true);
Boolean val2=Settings.Get("valueName2",true);
Settings.Set("valueName3",100);
Integer val3=Settings.Get("valueName3",100);

0

您可以通过以下方式加载属性文件:

InputStream is = new Test().getClass().getClassLoader().getResourceAsStream("app.properties");
        Properties props =  new Properties();
        props.load(is);

然后,您可以使用lambda表达式在地图上进行迭代,例如:

props.stringPropertyNames().forEach(key -> {
            System.out.println("Key is :"+key + " and Value is :"+props.getProperty(key));
        });

0

在我看来,当我们可以非常简单地执行以下操作时,不建议使用其他方法:

@PropertySource("classpath:application.properties")
public class SomeClass{

    @Autowired
    private Environment env;

    public void readProperty() {
        env.getProperty("language");
    }

}

它是如此简单,但我认为这是最好的方法!请享用

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.