【问题标题】:Reading UTF-8 file and writing plain ANSI?读取 UTF-8 文件并编写普通的 ANSI?
【发布时间】:2012-12-04 04:31:32
【问题描述】:

我有一个 UTF-8 文件(它是一个 csv)。
我需要逐行读取这个文件做一些替换,然后逐行写入另一个文件。

    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
        new FileOutputStream(fileFix), "ASCII")
    );
    bw.write("");   //clean current file


    BufferedReader br = new BufferedReader(new InputStreamReader(
        new FileInputStream(file),"UTF-8")
    );

    String line;
    while ((line = br.readLine()) != null) {
        line = line.replace(";", ",");
        bw.append(line + "\n");
    }

就这么简单。
问题是输出文件(fileFix)是UTF-8,我认为它有BOM字符。

如何在没有 BOM 的情况下将文件编写为纯 ANSI?

使用软件 (weka) 读取文件时遇到的错误

这个文件的第一行:

考虑一下 notepad++ 告诉我字符集是 UTF-8。如果我尝试将此文件转换为纯 ASCII(使用 Windows 记事本),则字符消失

解决方案

当你在第一行运行时:

line = line.substring(1);

删除任何 BOM 字符。

【问题讨论】:

  • 你想对任何不是你所指的 ANSI 编码的字符发生什么? (你指的是哪一个做?)
  • @JonSkeet:我不使用任何“异国情调”的字符。我的输入文件有标准A-Z0-9;,.
  • 问题是当我用软件(weka)打开我的输出文件时,第一个字符看起来很奇怪。如果我用记事本和 ANSI 字符集保存这个文件,问题就解决了
  • 我怀疑你的意思是 ASCII 或 ISO-8869-1 编码?如果不使用任何外来字符,UTF-8 与 ASCII 7 位相同。
  • 您的代码将删除 any 文件的第一个字符。这意味着如果它不以 BOM 开头,您将丢失数据。这是一个非常糟糕的主意。

标签: java


【解决方案1】:

听起来这是一个 BOM 问题,而不是编码问题。

您可以在编写文件时删除任何 BOM 字符,使用:

line = line.replace("\ufeff", "");

这就留下了您是否首先准确读取数据的问题...我强烈建议您根本不要使用FileWriter 和FileReader - 而是,使用InputStreamReader 和OutputStreamWriter,为它们明确指定编码。将阅读器编码设置为 UTF-8(假设输入文件确实是 UTF-8),并将编写器编码设置为您想要的任何内容......但老实说,我建议坚持使用 UTF-8。

还请注意,您应该在 finally 块中关闭您的阅读器/编写器,或者如果您使用的是 Java 7,则使用 try-with-resources 语句。

【讨论】:

  • 谢谢,我会试试的。我还编辑了我的问题,我添加了一些解释图片
  • 另外...我应该在我的第一个循环中添加替换吗?
  • @yes123:也可以——你不太可能在其他地方看到这个角色,但它不会造成任何伤害。
  • @JonSkeet 我认为根据en.wikipedia.org/wiki/Byte_order_mark替换utf-16 bom是错误的模式
  • @yes123:当您读取文件(以字节为单位)时,您指定了编码。这会将数据转换为 UTF-16 代码单元,而不管原始编码如何……因为这是 Java 用来存储文本的方式。 65279 = 0xfeff,即0xfe,0xff = 254, 255。不是“二十五万四千,二百五十五”。
【解决方案2】:

查看 http://en.wikipedia.org/wiki/Byte_order_mark 替换的模式,看起来像 EF BB BF 而不是 FE FF

这个解决方案是错误的检查 Jons answer intsead

【讨论】:

  • 如果您查看 UTF-8,您会看到有 BOM! 这真的是我得到的字符
  • 我试过这条线,但运气不好line = line.replace("\uefbbbf", ""); char 仍然存在
  • 我找到了解决方案,当您在第一行时:line = line.substring(1);
  • 不,这意味着要替换 字符 U+FEFF。如果 OP 为输入正确设置编码,我的解决方案应该可以正常工作。 EF BB BF 是要替换的 bytes 集合。代码不是在读取字节 - 它是在读取字符。使用line.substring(1) 只是避免了使用正确编码开始的问题。
  • @JonSkeet:我不知道输入文件的正确字符集是什么但是我知道会有BOM
猜你喜欢
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
  • 2018-06-13
  • 1970-01-01
相关资源
最近更新 更多