依赖默认编码,我应该使用什么,为什么?

FindBugs 报告了一个错误:

对默认编码的依赖 找到对方法的调用,该方法将执行字节到字符串(或字符串到字节)的转换,并假定默认平台编码是合适的。这将导致应用程序行为因平台而异。使用备用 API 并显式指定字符集名称或字符集对象。

我像这样使用FileReader(只是一段代码):

public ArrayList<String> getValuesFromFile(File file){
    String line;
    StringTokenizer token;
    ArrayList<String> list = null;
    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader(file));
        list = new ArrayList<String>();
        while ((line = br.readLine())!=null){
            token = new StringTokenizer(line);
            token.nextToken();
            list.add(token.nextToken());
    ...

要更正错误,我需要更改

br = new BufferedReader(new FileReader(file));

br = new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.defaultCharset()));

当我使用PrintWriter时,发生了同样的错误。所以现在我有一个问题。当我可以(应该)使用FileReader和PrintWriter时,如果这不是很好的做法,请依靠默认编码?第二个问题是正确使用Charset.defaultCharset ()?我决定使用此方法自动定义用户操作系统的字符集。


答案 1

理想情况下,它应该是:

try (InputStream in = new FileInputStream(file);
     Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
     BufferedReader br = new BufferedReader(reader)) {

...艺术

try (BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {

...假设文件编码为 UTF-8。

几乎每个不是Unicode转换格式的编码对于自然语言数据来说都是过时的。有些语言在没有 Unicode 的情况下是无法支持的。


答案 2

如果文件受应用程序控制,并且希望以平台的默认编码对文件进行编码,则可以使用默认平台编码。明确地指定它会让你和未来的维护者更清楚,这是你的意图。例如,对于文本编辑器来说,这将是一个合理的默认值,然后文本编辑器将写入此平台上的任何其他编辑器能够读取的文件。

另一方面,如果要确保任何可能的字符都可以写入文件中,则应使用通用编码,如 UTF8。

如果文件来自外部应用程序,或者应该与外部应用程序兼容,则应使用此外部应用程序期望的编码。

你必须意识到的是,如果你像在机器上一样写一个文件,然后像在另一台机器上一样读取它,这台机器没有相同的默认编码,你不一定能够阅读你写的东西。使用特定的编码,写入和读取,如UTF8,确保文件将始终相同,无论在写入文件时使用什么平台。


推荐