更新属性文件的更好方法是什么?

42
尽管java.util.properties允许读取和写入属性文件,但它的写入不保留格式。这并不奇怪,因为它没有与属性文件绑定。
是否有类似于PropertyFile的类,可以保留注释和空行,并在原地更新属性值?
8个回答

63

Apache的Commons Configuration API是最佳选择,提供了一种统一的方式从属性文件、XML、JNDI、JDBC数据源等获取配置。

对于属性文件的处理非常优秀。它允许你从属性文件生成一个PropertiesConfigurationLayout对象,尽可能地保留有关属性文件的信息(空格、注释等)。当你保存更改到属性文件时,这些更改将尽可能地被保留。


示例代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.PropertiesConfigurationLayout;

public class PropertiesReader {
    public static void main(String args[]) throws ConfigurationException, FileNotFoundException {
        File file = new File(args[0] + ".properties");

        PropertiesConfiguration config = new PropertiesConfiguration();
        PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config);
        layout.load(new InputStreamReader(new FileInputStream(file)));

        config.setProperty("test", "testValue");
        layout.save(new FileWriter("path\\to\\properties\\file.properties", false));
    }
}

另请参见:


1
这很好用,并保留了注释。我顺便添加了一些示例代码 :) - Patrick Boos
7
提供的代码无法编译,propsFile未声明。 - blank
如果你有一个键值对,例如Spring.Names = cookie@!jar@!johnson@!james@!green@!patrick。你该如何在Patrick之后添加“Jimmy”? - JayC

11

Patrick Boos贡献的使用Apache Commons Configuration库的示例代码不必要地复杂。除非需要对输出进行一些高级控制,否则不需要明确使用PropertiesConfigurationLayout。仅使用PropertiesConfiguration就足以保留注释和格式:

PropertiesConfiguration config = new PropertiesConfiguration("myprops.properties");
config.setProperty("Foo", "Bar");
config.save();

(注意:此代码适用于现有的1.10稳定版。我没有检查它是否适用于目前可用的2.0 alpha版本。)


这个方法是可行的。但问题在于,在键值对中,我们在“=”后面得到了一个空格,这是不必要的。因为我的值不需要空格。例如:test=xyz 是属性文件中的值。但是在运行上述代码后,我得到的是 test = xyz。我不需要在“xyz”之前有空格。 - Jince Martin
1
它与2.1.1版本不兼容,除了setProperty方法之外,这些方法都不存在。我非常好奇他们为什么要删除这样优雅的方法,比如save()... :( - GOXR3PLUS

7

configuration2类有不同的语法。以下是使用它们的示例:

import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.PropertiesConfigurationLayout;

public void test() {
    PropertiesConfiguration config = new PropertiesConfiguration();
    PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout();
    config.setLayout(layout);
    layout.load(config, new FileReader("config.properties"));

    config.setProperty("KEY", "VALUE");
    StringWriter stringWriter = new StringWriter();
    layout.save(config, stringWriter);
    LOG.debug("Properties:\n{}", stringWriter.toString());
}

7

根据文档,一个名为"PropertiesConfigurationLayout"的类将保留格式和注释。 - Aaron Digulla

1
    File file = new File("src/test/resources/1automation.properties");
    PropertiesConfiguration config = new PropertiesConfiguration();
    PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config);
    layout.load(new InputStreamReader(new FileInputStream(file)));
    FileWriter fw = new FileWriter("src/test/resources/1automation.properties",false);
    config.setProperty("myssi.admin.name", "testValue");
    layout.save(fw);

1
这个可以工作。但问题是,在key=value对中,我们在“=”后面得到了一个空格,这是不必要的。因为我的值不需要空格。 例如:test=xyz是属性文件中的值。但在运行上述代码后,我得到了test = xyz。我不需要在'xyz'之前有空格。 - Jince Martin
我的评论可能有点晚了,但是你总是可以使用 trim() 函数来去除不必要的空格。 - Rahul Jawale

1

针对Jince Martin在书写属性文件时遇到尾随空格的问题,例如key = value而不是key=value,我想提供一些解决方案。

您可以调用layout.setGlobalSeparator("=")来解决这个问题。


1
如果这是对某些事情的回应,请将其添加为评论而不是单独的答案。 - Derek C.
@DerekC。这需要50个声望点。他们还应该等到他们可以。 - Scratte

0
最佳答案中有一个小错误: 这一行:

PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config);

必须被替换为:

PropertiesConfigurationLayout layout = config.getLayout();

-1

我曾经看到过一个使用INI文件的类,但现在找不到链接了。如果您找不到其他东西,可以尝试DecentXML。我编写了这个XML解析器,其特定设计目标是完全保留原始格式(即包括注释、元素中的奇怪空格或根元素周围的所有内容)。

在解析生成的XML文档期间,您只需记住包含选项值的元素并替换其中的文本节点。保存时,未更改的内容将不会以任何方式发生变化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接