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

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

问题:

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

【问题讨论】:

    标签: java properties


    【解决方案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")”或其他一些已知位置。
    • 内特,这是真的。但是,在某些情况下,部署位置是未知的(例如,您的特定组件的所有内容都捆绑到某个存档中)。在这种情况下,可以很方便地说“它在那个类中,无论那个类最终在哪里”。此外,为了避免文件分散,可以将单个配置包用于所有属性文件。
    • Fabian,这两种情况都适用于我的评论 - 它基于类路径 - 而不是文件系统。
    • 对于任何试图让 Nate 的示例工作的人 - 应该用正斜杠替换反斜杠。所以在这种情况下:'class.getResourceAsStream("/file.properties")'
    【解决方案4】:

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

    1. 将文件存储在同一个包中。
    2. 推荐.properties 扩展,但您可以选择自己的。
    3. 使用位于java.util package => PropertiesListResourceBundleResourceBundle classes 的这些类。
    4. 要读取属性,请使用 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"));
    

    【讨论】:

    【解决方案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 数据存储中。我们只能使用以下类型的数据:

    1. 字符串
    2. 布尔值
    3. 浮动
    4. int
    5. 字节数组

    要加载属性文件,您可以提供绝对路径,或者如果属性文件存在于您的类路径中,则使用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】:

      按顺序:

      1. 您几乎可以将文件存储在任何地方。
      2. 无需扩展。
      3. Montecristo 有illustrated 如何加载这个。这应该可以正常工作。
      4. 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");
                        }
                    
                    }
                    

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

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-07-21
                      • 1970-01-01
                      • 1970-01-01
                      • 2019-09-29
                      • 2021-09-12
                      相关资源
                      最近更新 更多