阅读文件时找不到ZERO WIDTH NO-BREAK SPACE

时间:2014-10-16 14:50:50

标签: java file-io unicode intellij-idea

我在尝试解析从文件中获取的JSON字符串时遇到了问题。我的问题是,当我读取它时,零宽度不间断空格字符(unicode 0xfeff)位于我的字符串的开头,我无法摆脱它。我不想使用正则表达式,因为可能存在具有不同unicodes的其他隐藏字符。

这就是我所拥有的:

StringBuilder content = new StringBuilder();
    try {
        BufferedReader br = new BufferedReader(new FileReader("src/test/resources/getStuff.json"));
        String currentLine;
        while((currentLine = br.readLine()) != null) {
            content.append(currentLine);
        }
        br.close();
    } catch(Exception e) {
        Assert.fail();
    }

这是JSON文件的开头(复制粘贴整个过程太长了,但我确认它有效):

{"result":{"data":{"request":{"year":null,"timestamp":1413398641246,...

这是我到目前为止所尝试的内容:

  • 将JSON文件复制到记事本++并显示所有字符
  • 将文件复制到记事本++并转换为没有BOM的UFT-8和ISO 8859-1
  • 在其他文本编辑器中打开JSON文件,例如sublime并保存为UFT-8
  • 将JSON文件复制到txt文件并在
  • 中读取
  • 尝试使用Scanner而不是BufferedReader
  • 在intellij中我尝试了视图 - >主动编辑器 - >显示空白

如何在字符串开头没有零宽度不间断空格字符的情况下读取此文件?

1 个答案:

答案 0 :(得分:4)

0xEF 0xBB 0xBF是UTF-8 BOM0xFE 0xFF是UTF-16BE BOM0xFF 0xFE是UTF-16LE BOM }。如果字符串前面存在0xFEFF,则表示您创建了带有BOM的UTF编码文本文件。 UTF-16 BOM可以显示为0xFEFF,而如果BOM本身从UTF-8解码为UTF-16,则UTF-8 BOM仅显示为0xFEFF(意味着读者检测到BOM但没有跳过它)。事实上,众所周知,Java不处理UTF-8物料清单(请参阅错误JDK-4508058JDK-6378911)。

如果您阅读FileReader documentation,则会说:

  

此类的构造函数假定默认字符编码和默认字节缓冲区大小是合适的。要自己指定这些值,请在FileInputStream上构造一个InputStreamReader。

您需要使用识别字符集的阅读器来阅读文件内容,最好是为您读取BOM并根据需要在内部进行调整。但更糟糕的情况是,您可以自己打开文件,读取前几个字节以检测是否存在BOM,然后使用适当的字符集构建读取器以读取文件的其余部分。以下是使用org.apache.commons.io.input.BOMInputStream执行此操作的示例:

(来自https://stackoverflow.com/a/13988345/65863

String defaultEncoding = "UTF-8";
InputStream inputStream = new FileInputStream(someFileWithPossibleUtf8Bom);
try {
    BOMInputStream bOMInputStream = new BOMInputStream(inputStream);
    ByteOrderMark bom = bOMInputStream.getBOM();
    String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
    InputStreamReader reader = new InputStreamReader(new BufferedInputStream(bOMInputStream), charsetName);
    //use reader
} finally {
    inputStream.close();
}