【问题标题】:Removing the BOM character with Java [duplicate]用Java删除BOM字符[重复]
【发布时间】:2014-12-03 10:32:35
【问题描述】:

我正在尝试使用 FileReader 读取文件并将它们写入单独的文件。
这些文件是 UTF-8 编码的,但不幸的是其中一些仍然包含 BOM。
我试过的相关代码是这样的:

private final String UTF8_BOM = "\uFEFF";

 private String removeUTF8BOM(String s)
    {
        if (s.startsWith(UTF8_BOM))
        {
            s=s.replace(UTF8_BOM, "");
        }
        return s;
    }

    line=removeUTF8BOM(line);

但由于某种原因,BOM 没有被删除。有没有其他方法可以用 FileReader 做到这一点?我知道 BOMInputStream 应该可以工作,但我宁愿使用 FileReader 找到解决方案。

【问题讨论】:

标签: java filereader byte-order-mark


【解决方案1】:

问题的简单解决方案:

public static void main(final String[] args)
{
    final String hasbom = "\uFEFF" + "Hello World!";
    final String nobom = hasbom.charAt(0) == '\uFEFF' ? hasbom.substring(1) : hasbom;
    System.out.println(hasbom.equals(nobom));
}

输出:

false

正确的解决方法:

您永远不应针对基于File 的API 进行编程,而应针对InputStream/OutputStream 进行编程,以便您的代码可移植到不同的源位置。

这只是一个未经测试的示例,说明如何将此行为封装到 InputStream 中以使其透明。

public class BomProofInputStream extends InputStream
{
    private final InputStream is;

    public BomProofInputStream(@Nonnull final InputStream is)
    {
        this.is = is;
    }

    private boolean isFirstByte = true;

    @Override
    public int read() throws IOException
    {
        if (this.isFirstByte)
        {
            this.isFirstByte = false;
            final int b = is.read();
            if ("\uFEFF".charAt(0) != b) { return b; } 
        }
        return is.read();
    }
}

通过一些搜索找到了full fledged example

【讨论】:

    【解决方案2】:

    FileReader 类是一个旧的实用程序类,它使用平台编码。在可能不是 UTF-8 的 Windows 上。

    最好与其他班级一起阅读。

    作为娱乐,为了澄清错误,这里是一个肮脏的黑客,适用于具有单字节编码的平台:

    private final String UTF8_BOM = new String("\uFEFF".getBytes(StandardCharsets.UTF_8));
    

    这会获取 UTF-8 字节并以当前平台编码生成一个字符串。

    不用说 FileReader 是不可移植的,只处理本地文件。

    【讨论】:

      猜你喜欢
      • 2014-03-20
      • 2015-01-06
      • 2010-09-22
      • 2016-01-04
      • 1970-01-01
      • 2016-11-03
      • 2013-09-25
      • 2012-10-21
      相关资源
      最近更新 更多