读取文件时找不到零宽度无间隔
Posted
技术标签:
【中文标题】读取文件时找不到零宽度无间隔【英文标题】:Cannot find ZERO WIDTH NO-BREAK SPACE when reading file 【发布时间】:2014-10-16 14:50:49 【问题描述】:我在尝试解析从文件中获取的 JSON 字符串时遇到了问题。我的问题是零宽度不间断空格字符(unicode 0xfeff)在我读入时位于字符串的开头,我无法摆脱它。我不想使用正则表达式,因为可能存在其他具有不同 unicode 的隐藏字符。
这是我所拥有的:
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 文件复制到 notepad++ 并显示所有字符 将文件复制到 notepad++ 并转换为不带 BOM 和 ISO 8859-1 的 UFT-8 在 sublime 等其他文本编辑器中打开 JSON 文件并保存为 UFT-8 将 JSON 文件复制到 txt 文件中并读入 尝试使用 Scanner 而不是 BufferedReader 在 intellij 中,我尝试了查看 -> 活动编辑器 -> 显示空格如何在字符串开头没有零宽度不间断空格字符的情况下读取此文件?
【问题讨论】:
【参考方案1】:0xEF 0xBB 0xBF
是 UTF-8 BOM,0xFE 0xFF
是 UTF-16BE BOM,0xFF 0xFE
是 UTF-16LE BOM。如果 0xFEFF
存在于字符串的前面,则意味着您创建了一个带有 BOM 的 UTF 编码文本文件。 UTF-16 BOM 可能按原样显示为 0xFEFF
,而 UTF-8 BOM 仅在 BOM 本身从 UTF-8 解码为 UTF-16 时才会显示为 0xFEFF
(这意味着阅读器检测到 BOM但没有跳过它)。事实上,众所周知,Java 不处理 UTF-8 BOM(请参阅错误 JDK-4508058 和 JDK-6378911)。
如果您阅读FileReader
documentation,它会说:
此类的构造函数假定默认字符编码和默认字节缓冲区大小是适当的。要自己指定这些值,请在 FileInputStream 上构造一个 InputStreamReader。
您需要使用能够识别字符集的阅读器来读取文件内容,最好是能够为您读取 BOM 并根据需要在内部进行自我调整的阅读器。但更糟糕的情况是,您可以自己打开文件,读取前几个字节以检测是否存在 BOM,然后使用适当的字符集构建读取器来读取文件的其余部分。下面是一个使用 org.apache.commons.io.input.BOMInputStream
的示例,正是这样做的:
(来自https://***.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();
【讨论】:
太棒了,成功了。只是为了澄清一些事情,如果其他人读到这个。BomInputStream
的创建是删除 bom 的原因,您可以找到有关 here 的更多信息以上是关于读取文件时找不到零宽度无间隔的主要内容,如果未能解决你的问题,请参考以下文章