【问题标题】:Incorrect printing of non-eglish characters with Java使用 Java 打印非英文字符不正确
【发布时间】:2019-01-16 07:59:00
【问题描述】:

我认为这只是 Python 2 的问题,但现在在 java(Windows 10、JDK8)中遇到了类似的问题。

到目前为止,我的搜索几乎没有解决问题。

我从“stdin”输入流中读取了这个值:Viļāni。当我将它打印到控制台时,我得到了这个:Vi????ni

相关代码sn-ps如下:

   BufferedReader in = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));

    ArrayList<String> corpus = new ArrayList<String>();
    String inputString = null;
    while ((inputString = in.readLine()) != null) {
        corpus.add(inputString);
    }
    String[] allCorpus = new String[corpus.size()];
    allCorpus = corpus.toArray(allCorpus);
    for (String line : allCorpus) {
        System.out.println(line);
    }

我的问题进一步展开如下:

我读取了一个包含以下 2 行的文件: を Sōten_Kōro 当我从磁盘读取它并输出到第二个文件时,我得到以下输出:

ã‚’ SÅ�ten_KÅ�ro 当我使用 cat testinput.txt | java UTF8Tester 从标准输入读取文件时,我得到以下输出:

??? S??ten_K??ro

显然两者都是错误的。我需要能够将正确的字符打印到控制台和文件。我的示例代码如下:

public class UTF8Tester {

    public static void main(String args[]) throws Exception {
        BufferedReader stdinReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
        String[] stdinData = readLines(stdinReader);
        printToFile(stdinData, "stdin_out.txt");

        BufferedReader fileReader = new BufferedReader(new FileReader("testinput.txt"));
        String[] fileData = readLines(fileReader);
        printToFile(fileData, "file_out.txt");

    }

    private static void printToFile(String[] data, String fileName)
            throws FileNotFoundException, UnsupportedEncodingException {
        PrintWriter writer = new PrintWriter(fileName, "UTF-8");
        for (String line : data) {
            writer.println(line);
        }
        writer.close();
    }

    private static String[] readLines(BufferedReader reader) throws IOException {
        ArrayList<String> corpus = new ArrayList<String>();
        String inputString = null;

        while ((inputString = reader.readLine()) != null) {
            corpus.add(inputString);
        }
        String[] allCorpus = new String[corpus.size()];
        return corpus.toArray(allCorpus);
    }

}

真的被困在这里,我们将不胜感激!提前致谢。保罗

【问题讨论】:

  • 在 Eclipse、Windows 7 中运行时无法重现。您使用的控制台应用程序是否能够显示 UTF-8 字符?
  • 我在 Windows 上的 VS Code 终端中使用以下命令运行它:cat input.txt | java app

标签: java unicode utf-8 output inputstream


【解决方案1】:
  • System.in/out 将使用默认的 Windows 字符集。
  • Java 字符串将在内部使用 Unicode。
  • FileReader/FileWriter 是使用默认字符集的旧实用程序类,因此它们仅适用于不可移植的本地文件。

您看到的错误是两个字节 UTF-8 序列的特殊字符,但每个(特殊 UTF-8)字节都解释为默认的单字节编码,但值不存在,因此是 ? 的两倍替换。

  • 要求该字符可以在 System.in 中以默认字符集输入。
  • 然后字符串是从默认字符集转换而来的。
  • 以 UTF-8 写入文件需要指定 UTF-8。

因此:

    BufferedReader stdinReader = new BufferedReader(new InputStreamReader(System.in));
    String[] stdinData = readLines(stdinReader);
    printToFile(stdinData, "stdin_out.txt");

    Path path = Paths.get("testinput-utf8.txt");
    List<String> lines = Files.readAllLines(path); // Here the default is UTF-8!

    Path path = Paths.get("testinput-winlatin1.txt");
    List<String> lines = Files.readAllLines(path, "Windows-1252");

    Files.write(lines, Paths.get("file_out.txt"), StandardCharsets.UTF_8);

检查您当前的计算机系统是否处理日语:

System.out.println("Hiragana letter Wo '\u3092'."); // Either を or ?.

看到? 无法转换为默认系统编码。 を 是 U+3092,用 \u3092 将 u 编码为 ASCII。

在 Windows 下创建 UTF-8 文本:

Files.write(Paths.get("out-utf8.txt"),
    "\uFEFFHiragana letter Wo '\u3092'.".getBytes(StandardCharsets.UTF_8));

这里我使用了一个丑陋的(通常不需要的)BOM 标记字符\uFEFF(一个零宽度的空格),它可以让 Windows 记事本识别 UTF-8 格式的文本。

【讨论】:

  • 谢谢乔普。因此,如果我想使用 Files.readAllLines 从文件中读取数据,然后将其输出到另一个文件,则此方法有效。然而,我最大的问题是能够从标准输入读取它,然后输出到我继续挣扎的控制台。
  • 使用 System.in 和 out 必须遵守系统的编码(通常)。如果在 Windows 下编码是 Western Latin-1 (Windows-1252),那么对于希腊文、西里尔文和亚洲文字来说,这种情况就不妙了。存在应该能够使用的第 3 方控制台替换(JConsole?)。我也会添加一些代码。
  • 所以我仍然无法在 Windows 上运行它,所以我求助于在这些复杂性似乎不那么复杂的 Linux 上运行它。感谢所有 cmets。
  • 是的,毫无疑问,Linux 及其无处不在的 UTF-8 更加通用;为了这个目的,把它放在家里。我正在“等待”MS Windows 只使用 Unicode,谁知道 UTF-16 或 UTF-32。
猜你喜欢
  • 1970-01-01
  • 2015-02-08
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多