如何使用 Java 属性文件?

Posted

技术标签:

【中文标题】如何使用 Java 属性文件?【英文标题】:How to use Java property files? 【发布时间】:2010-11-22 01:06:18 【问题描述】:

我有一个配置值的键/值对列表,我想将其存储为 Java 属性文件,然后加载和迭代。

问题:

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

属性文件中不存在键时返回什么值? @MitakshGupta 如果在文件或默认属性列表中找不到具有您传递的名称的属性,则返回null。见Javadoc 这与properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); (即getResourceAsStreamFileInputStream)相比如何?利弊? 不关闭FileInputStream有问题吗?【参考方案2】:

可以将文件存储在您喜欢的任何位置。如果你想将它保存在你的 jar 文件中,你需要使用Class.getResourceAsStream()ClassLoader.getResourceAsStream() 来访问它。如果它在文件系统上,它会稍微容易一些。

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

使用Properties.load 加载文件,如果您使用的是Java 6,则传入InputStreamStreamReader。(如果您正在使用Java 6,我' d 可能对流使用 UTF-8 和 Reader,而不是默认的 ISO-8859-1 编码。)

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

【讨论】:

谢谢乔恩,接下来我知道我会在 joda 上查找一些内容,你也会回答这个问题。【参考方案3】:

如果你把属性文件和类Foo放在同一个包中,你可以很容易地用它来加载它

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

鉴于 Properties 扩展了 Hashtable,您可以像在 Hashtable 中那样迭代值。

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

【讨论】:

可以这样做 - 但我不喜欢将属性文件存储在同一个包中。您最终会得到分布在应用程序中各处的属性文件。我更愿意将所有属性文件存储在应用程序的根目录中,并将它们加载为“class.getResourceAsStream("\file.properties")”或其他一些已知位置。 内特,这是真的。但是,在某些情况下,部署位置是未知的(例如,您的特定组件的所有内容都捆绑到某个存档中)。在这种情况下,可以很方便地说“它在那个类中,无论那个类最终在哪里”。此外,为了避免文件分散,可以将单个配置包用于所有属性文件。 F***,这两种情况都适用于我的评论 - 它基于类路径 - 而不是文件系统。 对于任何试图让 Nate 的示例工作的人 - 应该用正斜杠替换反斜杠。所以在这种情况下:'class.getResourceAsStream("/file.properties")'【参考方案4】:

有很多方法可以创建和读取properties 文件:

    将文件存储在同一个包中。 推荐.properties 扩展,但您可以选择自己的。 使用位于java.util package => PropertiesListResourceBundleResourceBundle classes 的这些类。 要读取属性,请使用 Propertiesjava.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' 扩展有什么问题?请帮助我。 @atishshimpi 在使用 Properties 类型时不需要,但对于 ResourceBundle 是必需的 - 阅读文档-docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html【参考方案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。【参考方案6】:

属性已成为遗产。 Preferences 类优于属性。

偏好数据的分层集合中的一个节点。此类允许应用程序存储和检索用户和系统首选项和配置数据。此数据永久存储在依赖于实现的后备存储中。典型的实现包括平面文件、特定于操作系统的注册表、目录服务器和 SQL 数据库。这个类的用户不需要关心后备存储的细节。

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

    字符串 布尔值 双 浮动 int 长 字节数组

要加载属性文件,您可以提供绝对路径,或者如果属性文件存在于您的类路径中,则使用getResourceAsStream()

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>

看看这个article的偏好商店内部

【讨论】:

【参考方案7】:

例子:

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 个属性文件怎么办?【参考方案8】:

按顺序:

    您几乎可以将文件存储在任何地方。 无需扩展。 Montecristo 有illustrated 如何加载这个。这应该可以正常工作。 propertyNames() 为您提供了一个可迭代的枚举。

【讨论】:

2. no extension is necessary,请您提供此声明的任何参考。我对此感到困惑。 请注意,您可以通过输入流加载属性。因此,属性不知道输入流来自哪里(文件?套接字?),因此无法强制执行命名标准【参考方案9】:

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

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

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

在相关说明中,如果您使用现代框架,该框架可能会提供打开属性文件的其他方式。例如,Spring 提供了ClassPathResource 来使用 JAR 文件中的包名加载属性文件。

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

【讨论】:

【参考方案10】:

读取属性文件并将其内容加载到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());
    

【讨论】:

【参考方案11】:

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;

【讨论】:

【参考方案12】:

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

【讨论】:

【参考方案13】:

这是遍历属性的另一种方法:

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

【讨论】:

我很抱歉。我查看了 Zed 答案中的代码,它运行良好......我不知道当时我的想法......实际上他的解决方案比我的更好,我认为......【参考方案14】:

去年我写过关于这个属性框架的文章。 它将提供多种加载属性的方法,并具有强类型。

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

JHPropertiesTyped 将为开发人员提供强类型属性。 易于集成到现有项目中。 由大量的属性类型处理。 提供通过属性 IO 实现单行初始化属性的能力。 使开发人员能够创建自己的属性类型和属性 io。 网络演示也可用,如上图所示。 如果您选择使用它,还有一个用于管理属性的 Web 前端的标准实现。

项目网页上提供了完整的文档、教程、javadoc、faq 等。

【讨论】:

【参考方案15】:

这里准备好了静态类

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

【讨论】:

【参考方案16】:

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

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

【讨论】:

【参考方案17】:

在我看来,当我们可以很简单地做到这一点时,其他方式已被弃用,如下所示:

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

    @Autowired
    private Environment env;

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


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

【讨论】:

以上是关于如何使用 Java 属性文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何验证 Java 日志记录属性文件?

如何在 Java 中读取属性文件? [复制]

Spring:如何将属性文件提供给 Java.exe

如何在 JAVA 中使用 ResourceBundle 将匈牙利字符作为属性文件中的键?

如何配置 Spring bean 容器来加载 Java 属性文件?

如何在Eclipse中的Java项目中添加Java Properties文件