首页 > 解决方案 > .properties 文件必须在 java 9 之前以 ISO-8859-1 编码,这真的是真的吗?

问题描述

我经常读到 .properties 文件应该/必须在 Java 9 之前以 ISO-8859-1 编码。我从来没有遇到过以 UTF-8 加载和存储 .properties 的问题。还是建议仅对资源包文件使用 8859-1 ?

public static void utf8_test()
{
    Path pfile    = Paths.get("C:\\temp_\\properties_utf8.properties");
    Path pfileOut = Paths.get("C:\\temp_\\properties_utf-8_out.properties");
    Properties props = new Properties();

    try ( BufferedReader br = Files.newBufferedReader(pfile,StandardCharsets.UTF_8);
          BufferedWriter bw = Files.newBufferedWriter(pfileOut,StandardCharsets.UTF_8)
        )
    {
        props.load(br);
        props.setProperty("test","test prop;Гадание по телефону;öüµäß@;Euro sign;€");
        props.list(System.out);

        props.store(bw,"comment");

    } catch (Exception e) { e.printStackTrace(); }
} //--- end

The input file is:
foo = aaa
utf_test = Гадание
bar = bbb

The output file is:
#comment
#Wed Dec 25 15:11:28 CET 2019
utf_test=Гадание
bar=bbb
foo=aaa
test=test prop;Гадание по телефону;öüµäß@;Euro sign;€

标签: javaencodingproperties-file

解决方案


属性文件

Properties这是(Java 13)的类文档:

load(Reader)/方法以下面store(Writer, String)指定的简单的面向行的格式从基于字符的流中加载和存储属性。/方法与/对的工作方式相同,除了输入/输出流以 ISO 8859-1 字符编码load(InputStream)store(OutputStream, String)load(Reader)store(Writer, String)[强调添加] 进行编码。不能直接用这种编码表示的字符可以使用Java™ 语言规范第 3.3 节中定义的 Unicode 转义来编写;转义序列中只允许一个'u'字符。

loadFromXML(InputStream)和方法以简单的storeToXML(OutputStream, String, String)XML 格式加载和存储属性。默认情况下使用 UTF-8 字符编码,但是如果需要,可以指定特定的编码。实现需要支持 UTF-8 和 UTF-16,并且可能支持其他编码。XML 属性文档具有以下 DOCTYPE 声明:[...]

这是Properties#load(InputStream)(同样,Java 13)的文档:

从输入字节流中读取属性列表(键和元素对)。输入流采用简单的面向行的格式,如 中所述,load(Reader)假定使用 ISO 8859-1 字符编码[强调添加];也就是说,每个字节都是一个 Latin1 字符。非 Latin1 字符和某些特殊字符,使用Java™ 语言规范3.3 节中定义的 Unicode 转义在键和元素中表示。

此方法返回后,指定的流保持打开状态。


资源包

PropertyResourceBundle虽然这是(同样,Java 13)的类文档:

API 注释:

PropertyResourceBundle可以从表示属性文件的 anInputStream或 a构造。Reader从 an构造PropertyResourceBundle实例InputStream要求输入流以 UTF-8 编码。默认情况下,如果在读取输入流时发生 aMalformedInputException或 an UnmappableCharacterException,则PropertyResourceBundle实例重置为异常之前的状态,重新读取 ISO-8859-1 中的输入流,并继续读取。如果系统属性java.util.PropertyResourceBundle.encoding设置为“ISO-8859-1”或“UTF-8”,则输入流仅以该编码读取,并在遇到无效序列时抛出异常。如果指定了“ISO-8859-1”,则无法以 ISO-8859-1 编码表示的字符必须由Java™ 语言规范第 3.3 节中定义的 Unicode Escapes 表示而另一个采用 a 的构造函数Reader则没有这个限制。此系统属性忽略其他编码值。初始化此类时会读取和评估系统属性。初始化后更改或删除属性无效。

改变的是这个班级。如果您查看Java 8 文档,PropertyResourceBundle您会发现它在使用InputStream.


推荐阅读