无法从java中读取UTF-8文本文件中的特殊字母

时间:2013-05-20 20:53:48

标签: java encoding utf-8

我在java中遇到UTF-8编码问题。 我有一个UTF-8编码的.txt文件。我在notepad ++中检查过该文件实际上是UTF-8编码的。 我尝试读取文件,但特殊字母未正确显示。

我使用以下代码安静:

        try {

        Scanner sc = new Scanner(new FileInputStream("file.txt"), "UTF-8");

        String str;

        while(sc.hasNextLine()) {
            str = sc.nextLine();
            roadNames.add(str);
            System.out.println(str);
        }

        sc.close();

    } catch(IOException e1) {
        System.out.println("The file was not found....");
    }

它在eclipse中正确显示了特殊字母,我将默认编码定义为UTF-8,但不是在我生成的jar文件中。

对我来说唯一真正有用的是使用以下参数创建一个.bat文件“java -Dfile.encoding = utf-8 -jar executable.jar”,但我不认为这是一个很好的解决方案。

此外,这也有效:

PrintStream out = new PrintStream(System.out, true, "UTF-8"); 
out.println(str);

更新

当我说

  

特殊字母未正确显示

我的意思是System.out.println打印一个字符串,其中特殊字母被替换为├à而不是例如。

结果是

PrintStream out = new PrintStream(System.out, true, "UTF-8"); 
out.println(str);

毕竟不起作用 - 抱歉。

真正的问题不在于我希望控制台打印出文本文档中的内容,但文本文档中的每一行都包含一个名称,并且此名称将添加到ArrayList中。然后我有一个JTextField,当我开始在其中输入时,尝试通过在ArrayList中搜索最匹配的名称来自动完成我输入的内容。如果不是因为编码问题,这非常有效,因为JTextField中的特殊字母未正确显示。当我使用Dfile.encoding = utf-8参数

时,它才会正确显示

2 个答案:

答案 0 :(得分:1)

Java将使用平台默认编码,除非您指定其他内容。

听起来您的平台默认(Windows设置)不是UTF-8,因此在您未指定file.encoding属性或向PrintStream构造函数提供编码的情况下,使用默认编码。在这种情况下,当找到无法编码的字符时,使用该编码器的替换字符。这通常是' '或'?'。

操作系统指示可能无法显示您要打印的某些字符。您可以忽略该提示,并希望最好,或者您可以用保证显示的内容替换麻烦的字符。默认是替换;如果你想使用风险更大的方法,你必须明确。


更新:根据原始问题更新中提供的信息,听起来问题在于读取文件而不是输出。

使用平台默认编码是一种特殊情况。您应遵循的一般模式是每次将字节序列解码为字符串时明确指定编码。编码是您正在阅读的流所固有的,通常独立于您的代码正在运行的系统。例外情况是从控制台读取或类似情况。否则,应该有一些指定编码的元数据或约定,如HTTP标头,嵌入在文件中的属性,或某些需要特定编码的标准。

以下是如何从UTF-8编码的文件中读取您的道路名称:

Set<String> roadNames = new TreeSet<>();
try (InputStream bytes = new FileInputStream("file.txt")) {
  /* See how I'm specifying the UTF-8 encoding explicitly? */
  Reader chars = new InputStreamReader(bytes, StandardCharsets.UTF_8);
  BufferedReader lines = new BufferedReader(chars);
  while (true) {
    String line = lines.readLine();
    if (line == null)
      break;
    roadNames.add(line);
  }
}

答案 1 :(得分:0)

我有同样的问题。使用Charset.forName(“ cp866”),它将有所帮助。

BufferedReader brI = new BufferedReader(new InputStreamReader(cmd.getInputStream(), Charset.forName("cp866")));
        String result;
        while ((result = brI.readLine()) != null){
            System.out.println(result);
        }