加载多个属性文件
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
扩展 Hashtable
和 load()
只是在每个键值对上调用 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();
【讨论】:
以上是关于加载多个属性文件的主要内容,如果未能解决你的问题,请参考以下文章
spring boot 配置多个yaml文件并根据env参数加载