使用 PropertiesConfiguration 的属性文件多行值
Properties File multi-line values using PropertiesConfiguration
到目前为止,我有这个项目,我在其中使用 PropertiesConfiguration(来自 Apache)读取属性文件,编辑我想要编辑的值,然后将更改保存到文件中。它保留注释和格式等,但它确实改变的一件事是采用如下格式的多行值:
key=value1,\
value2,\
value3
并转成数组样式:
key=value1,value2,value3
我希望能够像以前那样打印那些格式化的行。
我通过这种方法做到了这一点:
PropertiesConfiguration config = new PropertiesConfiguration(configFile);
config.setProperty(key,value);
config.save();
我创建了一个解决方法,以防其他人需要此功能。此外,可能有更好的方法来执行此操作,但此解决方案目前对我有效。
首先,将 PropertiesConfiguration 分隔符设置为换行符,如下所示:
PropertiesConfiguration config = new PropertiesConfiguration(configFile);
config.setListDelimiter('\n');
然后您将需要遍历并更新所有属性(以设置格式):
Iterator<String> keys = config.getKeys();
while (keys.hasNext()) {
String key = keys.next();
config.setProperty(key,setPropertyFormatter(key, config.getProperty(key))) ;
}
使用此方法格式化您的值列表数据(如上所示):
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('[=12=]', ' ');
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;
}
那么差不多就对了,只是save函数把List中存储的双反斜杠,在文件中变成了4个反斜杠!所以你需要用一个反斜杠替换那些。我是这样做的:
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();
}
使用 commons-configuration2,您可以使用自定义 PropertiesWriter 实现来处理此类情况,如其 documentation 在“自定义属性读取器和写入器”下所述(Reader 有偏见)。
编写器提供了一种方法来管理要写入属性文件的每个字符的写入,因此您可以用它实现几乎任何您想要的东西(通过 PropertiesWriter.write(String)
)。还有一种方便的方法可以编写正确的换行符 (PropertiesWriter.writeln(String)
).
例如,我必须处理 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();
到目前为止,我有这个项目,我在其中使用 PropertiesConfiguration(来自 Apache)读取属性文件,编辑我想要编辑的值,然后将更改保存到文件中。它保留注释和格式等,但它确实改变的一件事是采用如下格式的多行值:
key=value1,\
value2,\
value3
并转成数组样式:
key=value1,value2,value3
我希望能够像以前那样打印那些格式化的行。
我通过这种方法做到了这一点:
PropertiesConfiguration config = new PropertiesConfiguration(configFile);
config.setProperty(key,value);
config.save();
我创建了一个解决方法,以防其他人需要此功能。此外,可能有更好的方法来执行此操作,但此解决方案目前对我有效。
首先,将 PropertiesConfiguration 分隔符设置为换行符,如下所示:
PropertiesConfiguration config = new PropertiesConfiguration(configFile);
config.setListDelimiter('\n');
然后您将需要遍历并更新所有属性(以设置格式):
Iterator<String> keys = config.getKeys();
while (keys.hasNext()) {
String key = keys.next();
config.setProperty(key,setPropertyFormatter(key, config.getProperty(key))) ;
}
使用此方法格式化您的值列表数据(如上所示):
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('[=12=]', ' ');
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;
}
那么差不多就对了,只是save函数把List中存储的双反斜杠,在文件中变成了4个反斜杠!所以你需要用一个反斜杠替换那些。我是这样做的:
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();
}
使用 commons-configuration2,您可以使用自定义 PropertiesWriter 实现来处理此类情况,如其 documentation 在“自定义属性读取器和写入器”下所述(Reader 有偏见)。
编写器提供了一种方法来管理要写入属性文件的每个字符的写入,因此您可以用它实现几乎任何您想要的东西(通过 PropertiesWriter.write(String)
)。还有一种方便的方法可以编写正确的换行符 (PropertiesWriter.writeln(String)
).
例如,我必须处理 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();