【问题标题】:BufferedOutputStream not working with Korean characters as expectedBufferedOutputStream 无法按预期使用韩语字符
【发布时间】:2021-10-11 14:29:39
【问题描述】:

我正在尝试将韩语字符写入文件,它正在写入一些乱码数据,当我在 CSV 中打开它时,我需要解决这些数据以显示为韩语数据。在没有解码回 UTF-8 并显示韩语数据的解决方法的情况下,如何实现我的要求。

    File localExport = File.createTempFile("char-test", ".csv");
    try (
            FileOutputStream fos = new FileOutputStream(localExport);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            OutputStreamWriter outputStreamWriter =
                    new OutputStreamWriter(bos, StandardCharsets.UTF_8)
    ) {
        ArrayList<String> rows = new ArrayList<>();
        rows.add("\"가짜 사용자\",사용자123,saint1_user123");
        rows.add("\"페이크유저루노도스트레스 성도1\",saint1_user1");
        for (int i=0; i<2; i++) {
            String csvUserStr = rows.get(i);
            outputStreamWriter.write(csvUserStr);
        }
    }

它正在写入以下数据,而不是我实际写入文件的数据。

【问题讨论】:

  • 你需要 UTF_16
  • 您正在查看如何准确地看待它,file.encoding 的价值是什么?
  • 使用 Unicode,应该定义所有字符。
  • 你确实需要 UTF-16,这是不正确的建议。
  • 不幸的是,他们认为不可接受的是 Excel 中的行为,而不是您的软件。

标签: java outputstream fileoutputstream bufferedoutputstream


【解决方案1】:

您的 java 代码绝对没有问题。你正在写那些字符,包括韩文,和写的一样。

你用什么工具来查看这个文件?

那是坏的。告诉它该文件是基于 UTF-8 的。如果你不能,找一个更好的工具或者找出它读取的编码,然后更新你的java代码。

请注意,CSV 文件、文本文件等 - 它们存储用于写入数据的编码。所有读/写文件的程序只需要知道它是什么编码,除了被告知之外没有其他方法可以知道。


更新:从评论看来,“正在阅读本文的工具”是 excel。

当您使用“导入 CSV”对话框时,Excel 会要求对文件进行编码。在下拉列表中选择 UTF-8。取决于您使用的版本/操作系统,但通常称为“文件来源”。

如果您希望您的客户端不需要乱用默认值,通常默认值是 MacRoman 或 Win1282 之类的东西,并且使用这样的编码,实际上 不可能 获得韩文字符。他们根本不在那个集合中。

如果您想要一劳永逸的方法,请自己生成 excel 文件,例如使用 Apache POI

【讨论】:

    【解决方案2】:

    CSV 文件无法在文件本身中“带内”携带编码信息。我猜用于 Excel CSV 导入的默认字符编码是系统默认值,所以如果这不是韩语,他们将不得不在导入 CSV 时指定编码。如果您的客户需要 CSV, 他们别无选择,只能接受这种行为。

    但是,如果他们的要求是在 Excel 中打开您的文件(而不是文件必须是 CSV 格式),您可以编写一个 Excel 电子表格。各种 Excel 文件格式确实包含字符编码信息,因此它们无需手动指定编码即可打开文件。

    库建议是题外话,但像 Apache POI 这样的库让编写简单的 Excel 工作表变得相当容易。还有其他好处,例如为您处理任何必要的转义,这样当电子表格中包含意外值时,您的文件就不会反复中断。

    【讨论】:

      【解决方案3】:

      如前所述,Excel 无法检测到文本是以 UTF-8 编码的。一种解决方案是写一个不可见的 BOM 字符作为第一个:

        outputStreamWriter.write("\uFEFF");
        for...
      

      这通常是杂项 UTF 编码的多余且丑陋的标记。

      顺便看看Files类,可以把代码减少到一行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        • 2011-01-19
        • 1970-01-01
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多