简体   繁体   English

使用 PropertiesConfiguration 的属性文件多行值

[英]Properties File multi-line values using PropertiesConfiguration

So far, I have this project where I read in a properties file using PropertiesConfiguration (from Apache), edit the values I would like to edit, and then save change to the file.到目前为止,我有这个项目,我使用 PropertiesConfiguration(来自 Apache)在属性文件中读取,编辑我想要编辑的值,然后将更改保存到文件。 It keeps the comments and formatting and such, but one thing it does change is taking the multi-line values formatted like this:它保留注释和格式等,但它确实改变的一件事是采用如下格式的多行值:

key=value1,\
    value2,\
    value3

and turns it into the array style:并将其转换为数组样式:

key=value1,value2,value3

I would like to be able to print those lines formatted as the were before.我希望能够打印那些格式化为以前的行。
I did this via this method:我通过这种方法做到了这一点:

PropertiesConfiguration config = new PropertiesConfiguration(configFile);
config.setProperty(key,value);
config.save();

I created a work around in case anyone else needs this functionality.我创建了一个解决方法,以防其他人需要此功能。 Also, there is probably a better way to do this, but this solution currently works for me.此外,可能有更好的方法来做到这一点,但这个解决方案目前对我有用。

First, set your PropertiesConfiguration delimiter to the new line character like so:首先,将 PropertiesConfiguration 分隔符设置为新行字符,如下所示:

PropertiesConfiguration config = new PropertiesConfiguration(configFile);
config.setListDelimiter('\n');

Then you will need to iterate through and update all properties (to set the format):然后您需要遍历并更新所有属性(以设置格式):

Iterator<String> keys = config.getKeys();
    while (keys.hasNext()) {
        String key = keys.next();

        config.setProperty(key,setPropertyFormatter(key, config.getProperty(key))) ;

    }

use this method to format your value list data (as shown above):使用此方法格式化您的值列表数据(如上所示):

private List<String> setPropertyFormatter(String key, Object list) {
    List<String> tempProperties = new ArrayList<>();
    Iterator<?> propertyIterator = PropertyConverter.toIterator(list, '\n');;
    String indent = new String(new char[key.length() + 1]).replace('\0', ' ');

    Boolean firstIteration = true;
    while (propertyIterator.hasNext()) {
        String value = propertyIterator.next().toString();

        Boolean lastIteration = !propertyIterator.hasNext();

        if(firstIteration && lastIteration) {
            tempProperties.add(value);
            continue;
        }

        if(firstIteration) {
            tempProperties.add(value + ",\\");
            firstIteration = false;
            continue;
        }

        if (lastIteration) { 
            tempProperties.add(indent + value);
            continue;
        } 

        tempProperties.add(indent + value + ",\\");
    }



    return tempProperties;
}

Then it is going to be almost correct, except the save function takes the double backslash that is stored in the List, and turns it into 4 back slashes in the file!那么它几乎是正确的,除了 save 函数将存储在 List 中的双反斜杠,并将其变成文件中的 4 个反斜杠! So you need to replace those with a single backslash.所以你需要用一个反斜杠替换它们。 I did this like so:我是这样做的:

try {
        config.save(new File(filePath));


        byte[] readIn = Files.readAllBytes(Paths.get(filePath));
        String replacer = new String(readIn, StandardCharsets.UTF_8).replace("\\\\\\\\", "\\");

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, false), "UTF-8"));
        bw.write(replacer);
        bw.close();

} catch (ConfigurationException | IOException e) {
        e.printStackTrace();
}

With commons-configuration2, you would handle such cases with a custom PropertiesWriter implementation, as described in its documentation under "Custom properties readers and writers" (Reader biased though).使用 commons-configuration2,您可以使用自定义 PropertiesWriter 实现来处理此类情况,如“自定义属性读取器和写入器”下的文档中所述(尽管偏向于读取器)。

A writer provides a way to govern writing of each character that is to be written to the properties file, so you can achieve pretty much anything you desire with it (via PropertiesWriter.write(String) ).编写器提供了一种方法来管理要写入属性文件的每个字符的写入,因此您可以使用它实现几乎任何您想要的东西(通过PropertiesWriter.write(String) )。 There is also a convenient method that writes proper newlines ( PropertiesWriter.writeln(String) ).还有一种方便的方法可以编写正确的换行符( PropertiesWriter.writeln(String) )。

For example, I had to handle classpath entries in a Netbeans Ant project project.properties file:例如,我必须处理 Netbeans Ant 项目 project.properties 文件中的类路径条目:

public class ClasspathPropertiesWriter extends PropertiesConfiguration.PropertiesWriter {
    
    public ClasspathPropertiesWriter(Writer writer, ListDelimiterHandler delimiter) {
        super(writer, delimiter);
    }

    @Override
    public void writeProperty(String key, Object value, boolean forceSingleLine) throws IOException {
        switch (key) {
            case "javac.classpath":
            case "run.classpath":
            case "javac.test.classpath":
            case "run.test.classpath":
                String str = (String) value;
                String[] split = str.split(":");
                if (split.length > 1) {
                    write(key);
                    write("=\\");
                    writeln(null);
                    for (int i = 0; i < split.length; i++) {
                        write("    ");
                        write(split[i]);
                        if (i != split.length - 1) {
                            write(":\\");
                        }
                        writeln(null);
                    }
                    
                } else {
                    super.writeProperty(key, value, forceSingleLine);
                }                
                break;

            default:
                super.writeProperty(key, value, forceSingleLine);
                break;
        }
        
    }
    
}
public class CustomIOFactory extends PropertiesConfiguration.DefaultIOFactory {

    @Override
    public PropertiesConfiguration.PropertiesWriter createPropertiesWriter(
            Writer out, ListDelimiterHandler handler) {
        return new ClasspathPropertiesWriter(out, handler);
    }
    
}
Parameters params = new Parameters();
FileBasedConfigurationBuilder<Configuration> builder =
    new FileBasedConfigurationBuilder<Configuration>(PropertiesConfiguration.class)
    .configure(params.properties()
        .setFileName("project.properties")
        .setIOFactory(new CustomIOFactory());
Configuration config = builder.getConfiguration();
builder.save();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM