如何在不覆盖整个文件的情况下覆盖.properties中的一个属性?

2022-09-01 12:01:41

基本上,我必须通过Java应用程序覆盖.properties文件中的某个属性,但是当我使用Legits.setProperty()并 Properties.Store()时,它会覆盖整个文件,而不仅仅是那个属性。

我尝试过使用 append = true 构造 FileOutputStream,但它添加了另一个属性,并且不会删除/覆盖现有属性。

如何对其进行编码,以便设置一个属性将覆盖该特定属性,而不会覆盖整个文件?

编辑:我尝试读取文件并添加到其中。这是我更新的代码:

FileOutputStream out = new FileOutputStream("file.properties");
FileInputStream in = new FileInputStream("file.properties");
Properties props = new Properties();

props.load(in);
in.close();

props.setProperty("somekey", "somevalue");
props.store(out, null);
out.close();

答案 1

API 不提供任何用于在属性文件中添加/替换/删除属性的方法。API 支持的模型是从文件加载所有属性,对内存中对象进行更改,然后将所有属性存储到一个文件(相同或不同的文件)。PropertiesProperties

但API在这方面并不罕见。实际上,如果不重写整个文件,就地更新文本文件很难实现。这种困难是现代操作系统实现文件/文件系统方式的直接后果。Properties

如果确实需要执行增量更新,则需要使用某种数据库来保存属性,而不是“.properties”文件。


其他答案以各种形式提出了以下方法:

  1. 将属性从文件加载到对象中。Properties
  2. 更新对象。Properties
  3. 将对象保存在现有文件之上。Properties

这适用于某些用例。但是,加载/保存可能会对属性进行重新排序,删除嵌入的注释和空白区域。这些事情可能很重要1.

另一点是,这涉及重写整个属性文件,OP显式尝试2来避免这种情况。


1 - 如果 API 按设计器的预期使用,则属性顺序、嵌入注释等无关紧要。但让我们假设OP这样做是出于“务实的原因”。
2 - 并不是说避免这种情况是可行的;请参阅前面。


答案 2

您可以使用Apache Commons Configuration中的 PropertiesConfiguration

在版本 1.X 中:

PropertiesConfiguration config = new PropertiesConfiguration("file.properties");
config.setProperty("somekey", "somevalue");
config.save();

从版本 2.0 开始:

Parameters params = new Parameters();
FileBasedConfigurationBuilder<FileBasedConfiguration> builder =
    new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
    .configure(params.properties()
        .setFileName("file.properties"));
Configuration config = builder.getConfiguration();
config.setProperty("somekey", "somevalue");
builder.save();