加载多个属性文件

Posted

技术标签:

【中文标题】加载多个属性文件【英文标题】:Loading multiple properties files 【发布时间】:2012-04-28 04:52:07 【问题描述】:

是否可以在 Java 中堆叠加载的属性?例如我可以这样做:

Properties properties = new Properties();

properties.load(new FileInputStream("file1.properties"));
properties.load(new FileInputStream("file2.properties"));

并访问两者的属性?

【问题讨论】:

是的,如果属性有不同的名称。不,如果属性具有相同的名称。如果属性名称冲突,您必须自己提供堆叠。 【参考方案1】:

你可以这样做:

Properties properties = new Properties();

properties.load(new FileInputStream("file1.properties"));

Properties properties2 = new Properties();
properties2.load(new FileInputStream("file2.properties"));

properties.putAll(properties2);

注意:维护的所有密钥都是唯一的。因此,稍后使用相同键加载的属性将被覆盖。只是为了你的参考:)

【讨论】:

如果 file2.properties 包含与 file1.properties 中定义的属性同名的属性,则只会显示 file2.properties 中这些属性的值。 对。您不能同时保留两个属性,因为键必须是唯一的。 推荐的方式是在构造函数中传递默认的属性文件。 Properties extends Map 只是一个实现细节。 @Puce - Properties 没有以文件名作为参数的构造函数。 你说的是真的,但它并没有回答帖子发起人提出的问题。 @tskuzzy 的答案实际上是正确的答案。【参考方案2】:

是的,属性堆栈。 Properties 扩展 Hashtableload() 只是在每个键值对上调用 put()

来自Source的相关代码:

String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf); 
String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf); 
put(key, value); 

换句话说,从文件加载不会清除当前条目。但是请注意,如果两个文件包含具有相同键的条目,则第一个将被覆盖。

【讨论】:

推荐的方式是在构造函数中传递默认的属性文件。 Properties extends Map 只是一个实现细节。 Properties 合同未声明此行为(换句话说,未记录使用未记录功能的所有可能后果)。 这是事实,应予以考虑。我只对实际结果感兴趣,而不是记录在案的行为。 "Properties 扩展java.util.Hashtable。" (来源:docs.oracle.com/javase/tutorial/essential/environment/…)【参考方案3】:

事实上,是的。你可以这样做。如果任何属性重叠,新加载的属性将取代旧的。

【讨论】:

【参考方案4】:

是的,您需要在构造函数中传递默认属性文件。像这样你可以把它们串起来。

例如:

Properties properties1 = new Properties();
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file1.properties")))
    properties1.load(bis);


Properties properties2 = new Properties(properties1);
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file2.properties")))
    properties2.load(bis);

【讨论】:

一开始我很喜欢这个,但现在我有所保留。暂且不说 BufferedInputStream 的使用,这比 OP 的代码好多少?在这两种情况下,您都将第二个文件直接加载到包含第一个文件属性的 Properties 对象中。但在本例中,您正在创建一个新的属性对象。有什么好处? 如果您使用此方法,并且出于某种原因正在迭代属性,您必须使用propertyNames()stringPropertyNames() 来获取要迭代的列表。如果使用底层的Map 方法,如entrySet()keySet(),则不会包含构造函数中指定的属性。【参考方案5】:

这也应该有效。如果 file1.properties 和 file2.properties 中定义了相同的属性,则 file2.properties 中的属性将生效。

    Properties properties = new Properties();
    properties.load(new FileInputStream("file1.properties"));
    properties.load(new FileInputStream("file2.properties"));

现在属性映射将具有来自两个文件的属性。如果 file1 和 file2 中出现相同的键,则 file1 中的键的值将在属性中更新为 file2 中的值,因为我调用的是 file1 然后是 file2。

【讨论】:

【参考方案6】:

您可以更动态地执行此操作,处理不确定数量的文件。

此方法的参数应该是一个包含属性文件路径的列表。我将方法设为静态,将其放在具有其他消息处理相关功能的类中,并在需要时调用它:

public static Properties loadPropertiesFiles(LinkedList<String> files) 
    try 
        Properties properties = new Properties();

                for(String f:files) 
                    Resource resource = new ClassPathResource( f );
                    Properties tempProp = PropertiesLoaderUtils.loadProperties(resource);
                    properties.putAll(tempProp);
                
                return properties;
    
    catch(IOException ioe) 
                return new Properties();
    

【讨论】:

以上是关于加载多个属性文件的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX 2 和国际化加载属性文件

spring boot 配置多个yaml文件并根据env参数加载

无法使用 pickle 和多个模块加载文件

Spring 3.0 中的多个属性文件

springboot加载指定的属性文件(properties和yml文件)

让 IntelliJ 知道属性文件