你如何逃避属性文件中的冒号(:)?

时间:2012-05-22 09:13:25

标签: java properties escaping key-value colon

我正在使用属性文件来存储我的应用程序的配置值。 在其中一个实例中,我必须将值存储为 xxx:yyy:zzz。当我这样做时,冒号使用反斜杠\进行转义,结果在属性文件中显示为xxx\:yyy\:zzz

我知道冒号:Properties Java类的标准分隔符。但是,我仍然需要保存该值而不使用反斜杠\

有关如何处理此事的任何建议吗?

8 个答案:

答案 0 :(得分:17)

将属性放入Properties对象并使用store(...)方法保存。该方法将执行所需的任何转义。 Java documentation说:

  

“...对于密钥,所有空格字符都使用前面的\字符写入。对于元素,前导空格字符,但不是嵌入或尾随空格字符,使用前面的\字符写入。键和元素字符#,!,=和:用前面的反斜杠写成,以确保它们正确加载。“

如果您手动创建/编写文件,则只需手动转义字符。


相反,如果您希望文件包含未转义的冒号字符,那么您就不走运了。此类文件格式错误,可能无法使用Properties.load(...)方法正确加载。如果你沿着这条路走下去,你需要实现自己的自定义加载和/或存储方法。

答案 1 :(得分:5)

我遇到了同样的问题。正斜杠/也会被store()中的Properties方法转义。

我通过创建自己的CustomProperties课程(扩展java.util.Properties)并在saveConvert()方法中注释了对customStore0()的调用来解决了这个问题。

这是我的CustomProperties课程:

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;

public class CustomProperties extends Properties {
  private static final long serialVersionUID = 1L;
  @Override
  public void store(OutputStream out, String comments) throws IOException {
      customStore0(new BufferedWriter(new OutputStreamWriter(out, "8859_1")),
                   comments, true);
  }
  //Override to stop '/' or ':' chars from being replaced by not called 
  //saveConvert(key, true, escUnicode)
  private void customStore0(BufferedWriter bw, String comments, boolean escUnicode)
          throws IOException {
      bw.write("#" + new Date().toString());
      bw.newLine();
      synchronized (this) {
          for (Enumeration e = keys(); e.hasMoreElements();) {
              String key = (String) e.nextElement();
              String val = (String) get(key);
              // Commented out to stop '/' or ':' chars being replaced
              //key = saveConvert(key, true, escUnicode);
              //val = saveConvert(val, false, escUnicode);
              bw.write(key + "=" + val);
              bw.newLine();
          }
      }
      bw.flush();
  }
}

答案 2 :(得分:3)

几天前我们遇到了这个问题。我们使用URL作为值来操作现有的属性文件。

风险很大但如果您的属性值小于40个字符,那么您可以使用“list”方法而不是“store”:

http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html#list(java.io.PrintWriter)

我们快速浏览了JDK代码并破解了可用于我们目的的自定义商店实现:

public void store(Properties props, String propertyFilePath) throws FileNotFoundException {
    PrintWriter pw = new PrintWriter(propertyFilePath); 
    for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
        String key = (String) e.nextElement();
        pw.println(key + "=" + props.getProperty(key));
    }
    pw.close();
}

答案 3 :(得分:1)

如果您使用属性文件的xml变体(使用loadFromXMLstoreToXML),这应该不是问题。

答案 4 :(得分:1)

很简单, 只需在那儿使用撇号 '' 例如:

代替这种情况(案例1)

File file= new File("f:\\properties\\gog\\esave\\apple");
prop.setProperty("basedir",flie.toString());

使用此(案例2)

File file= new File("f':'\\properties\\gog\\esave\\apple");
prop.setProperty("basedir",flie.toString());

输出将为


案例1:basedir = f:\ properties \ gog \ esave \ apple

案例2:basedir = f:\ properties \ gog \ esave \ apple

希望这对您有帮助

答案 5 :(得分:0)

尝试使用unicode。

冒号的unicode是\u003A

另外,空格的unicode是:\u0020

有关基本拉丁字符的列表,请参见:https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)

例如:

ProperName\u003A\NameContinues=Some property value

期望带有键的属性:

ProperName:NameContinues

,其值为:

Some property value

答案 6 :(得分:0)

对我来说,它是通过在特殊字符前使用\来实现的,

例如,

Before: VCS\u003aIC\u0020Server\u003a=Migration
After: VCS\:IC\ Server\:=Migration

:使用\: (空格)使用\ 进行转义(\后跟)。

有关更多信息:https://en.wikipedia.org/wiki/.properties

答案 7 :(得分:0)

对于像我这样在使用 Spring Boot 配置属性文件时为此而来的人:您需要将其括在 [..] 中:

例如:

my.test\:key=value

还不够,您需要在 application.properties 中使用它,例如:

my.[test\:key]=value

另见SpringBoot2 ConfigurationProperties removes colon from yaml keys