Java 属性反斜杠

Posted

技术标签:

【中文标题】Java 属性反斜杠【英文标题】:Java Properties backslash 【发布时间】:2021-11-19 18:23:25 【问题描述】:

我正在使用 Java 属性来读取属性文件。一切正常,但 Properties 默默地删除了反斜杠。

(即)

original: c:\sdjf\slkdfj.jpg

after: c:sdjfslkdfj.jpg

如何让属性不这样做?

我正在使用代码prop.getProperty(key)

我正在从文件中获取属性,并且我想避免添加双反斜杠

【问题讨论】:

此处描述的属性文件的语法:download.oracle.com/javase/6/docs/api/java/util/… 反斜杠用于转义字符序列和分割行。另请注意,您可以在 Windows 中对路径名使用普通的“/”斜杠。 【参考方案1】:

使用双反斜杠c:\\sdjf\\slkdfj.jpg

Properties props = new Properties();
props.setProperty("test", "C:\\dev\\sdk\\test.dat");
System.out.println(props.getProperty("test"));    // prints C:\dev\sdk\test.dat

UPDATE 信用到 @ewh 下面。显然,Windows 可以识别正斜杠。所以,我想你可以让你的用户用正斜杠代替,如果你之后需要反斜杠,你可以做一个替换。我在下面测试了这个 sn-p,它工作正常。

Properties props = new Properties();
props.setProperty("test", "C:/dev/sdk/test.dat");
System.out.println(props.getProperty("test"));   // prints C:/dev/sdk/test.dat

【讨论】:

我想避免使用双反斜杠,因为我从用户编写的文件中获取属性。 抱歉 - 您最初的帖子中没有该信息。如果你在 windows/DOS 文件系统上,那么恐怕你运气不好。 您在 Windows 系统上并非不走运。您实际上可以在 Windows 系统上的路径名中使用正斜杠。我通常在 java 属性文件中这样做以避免与反斜杠混淆。【参考方案2】:

是Properties.load() 导致了您看到的问题,因为反斜杠用于特殊目的。

包含所有数据的逻辑行 对于一个关键元素对可能会传播 穿过几个相邻的自然 通过转义行终止符来换行 带有反斜杠字符的序列, \.

如果您无法使用 CoolBeans 的建议,那么您可以做的是预先将属性文件读取为字符串并将反斜杠替换为双反斜杠,然后将其提供给 Properties.load()

String propertyFileContents = readPropertyFileContents();

Properties properties = new Properties();
properties.load(new StringReader(propertyFileContents.replace("\\", "\\\\")));

【讨论】:

不再识别多行属性值。请参阅我的帖子以获取解决方案。【参考方案3】:

使用正向斜线。 Java 中从不需要在文件名中使用反斜杠。

【讨论】:

【参考方案4】:

如果您确实需要在要加载的属性文件中使用反斜杠(例如对于不是文件路径的属性)为每个反斜杠字符输入\u005c

如@unhillbilly 提供的文档中所示,反斜杠在属性文件中被特殊处理。

@EJP:如果您想将 NTLM 登录 ID 存储在属性文件中,则肯定需要反斜杠,其中格式为带有反斜杠的 DOMAIN\USERNAME。这种类型的属性不是文件名,因此正斜杠不起作用。

编辑:@Max Nanasy:来自上述文件 (java.util.Properties load javadoc)(强调我的)

该方法不会将无效转义字符之前的反斜杠字符“\”视为错误; 反斜杠被静默删除。例如,在 Java 字符串中,序列“\z”会导致编译时错误。相比之下,这种方法会默默地删除反斜杠。因此,该方法将两个字符序列“\b”视为等同于单个字符'b'

对我来说,我总是在属性文件中遇到反斜杠问题(即使使用双反斜杠“\\”),除非我指定了 unicode。

【讨论】:

为什么要使用\u005c 而不是`\\`?它的可读性较差,打字较多。 另外,我如何在 Stack Exchange 评论中像代码一样格式化“\\”? @MaxNanasy 使用反引号 // @Alex 这适用于正斜杠 (//),但我似乎无法让它与反斜杠 (`\`) 一起使用。 @Max Nanasy:OP 询问的是从 files 加载属性,而不是通过 Java 字符串文字设置属性。引用的load 文档用于加载属性文件。【参考方案5】:

以下代码会有所帮助:

BufferedReader metadataReader = new BufferedReader(new InputStreamReader(new FileInputStream("migrateSchemaGenProps.properties")));
Properties props = new Properties();
props.load(new StringReader(IOUtils.getStringFromReader(metadataReader).replace("\\", "/")));

【讨论】:

你需要一个replaceAll,因为属性文件中可以有多个反斜杠 @OlivierFaucheux 错了。 See the javadoc @OlivierFaucheux 错了。请参阅Javadoc:replace 替换所有出现的情况。 replaceAll 不起作用,因为 '\\' 不是有效的正则表达式。【参考方案6】:

在属性文件中使用反斜杠并不是一件好事,因为它们是转义字符。

尽管如此:Windows 用户倾向于在任何路径中使用它们...因此,在一行中感谢 apache common IO:

params.load(new StringReader(IOUtils.toString(paramFile.toURI(), null).replaceAll("\\\\", "/")));

【讨论】:

【参考方案7】:

除了 Bala R 的回答之外,我还有以下解决方案,甚至可以在行尾保留反斜杠的换行语义。

这是我的代码:

private static Reader preparePropertyFile(File file) throws IOException 

    BufferedReader reader = new BufferedReader(new FileReader(file));
    StringBuilder result = new StringBuilder();

    String line;
    boolean endingBackslash = false;

    while ((line = reader.readLine()) != null) 
        line = line.trim();
        if (endingBackslash) 

            // if the line is empty, is a comment or holds a new property
            // definition the backslash found at the end of the previous
            // line is not for a multiline property value.
            if (line.isEmpty()
                    || line.startsWith("#")
                    || line.matches("^\\w+(\\.\\w+)*=")) 

                result.append("\\\\");
            
        

        // if a backslash is found at the end of the line remove it
        // and decide what to do depending on the next line.
        if (line.endsWith("\\")) 
            endingBackslash = true;
            line = line.substring(0, line.length() - 1);
         else 
            endingBackslash = false;
        
        result.append(line.replace("\\", "\\\\"));
    
    if (endingBackslash) 
        result.append("\\\\");
    
    return new StringReader(result.toString());


private static Properties getProperties(File file) throws IOException 
    Properties result = new Properties();
    result.load(preparePropertyFile(file));
    return result;

【讨论】:

【参考方案8】:

\ 替换为\\ 如下:

c:\sdjf\slkdfj.jpg 

c:\\sdjf\\slkdfj.jpg

【讨论】:

【参考方案9】:

你三次使用反斜杠得到一个: 例如: 键=值1\\值2 在属性文件中将变为 键=值1\值2 在 java Properties 对象中

【讨论】:

以上是关于Java 属性反斜杠的主要内容,如果未能解决你的问题,请参考以下文章

Java:replaceAll 不适用于反斜杠?

java反斜杠替换

sed命令反斜杠的转义

CSS min-height 属性中的反斜杠 [重复]

路径中 斜杠/和反斜杠 的区别

为啥JSON字符串当中会出现反斜杠?