oni*_*unn 62 java encoding file
我正在通过FileReader读取文件 - 该文件是UTF-8解码的(带有BOM)现在我的问题是:我读取文件并输出一个字符串,但遗憾的是BOM标记也输出了.为什么会这样?
fr = new FileReader(file);
br = new BufferedReader(fr);
String tmp = null;
while ((tmp = br.readLine()) != null) {
String text;
text = new String(tmp.getBytes(), "UTF-8");
content += text + System.getProperty("line.separator");
}
Run Code Online (Sandbox Code Playgroud)
第一行后的输出
?<style>
Run Code Online (Sandbox Code Playgroud)
Rea*_*wTo 71
在Java中,您必须手动使用UTF8 BOM(如果存在).Java bug数据库中记录了此行为,此处和此处.暂时没有解决方法,因为它会破坏JavaDoc或XML解析器等现有工具.在Apache的IO共享提供了一个BOMInputStream处理这种情况.
看看这个解决方案:处理带有BOM的UTF8文件
fin*_*nnw 33
最简单的修复可能只是\uFEFF从字符串中删除结果,因为它几乎不可能出于任何其他原因.
tmp = tmp.replace("\uFEFF", "");
Run Code Online (Sandbox Code Playgroud)
另请参阅此番石榴错误报告
pee*_*nut 26
类: org.apache.commons.io.input.BOMInputStream
用法示例:
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();
}
Run Code Online (Sandbox Code Playgroud)
以下是我使用Apache BOMInputStream的方法,它使用了try-with-resources块."false"参数告诉对象忽略以下BOM(出于安全原因,我们使用"无BOM"文本文件,哈哈):
try( BufferedReader br = new BufferedReader(
new InputStreamReader( new BOMInputStream( new FileInputStream(
file), false, ByteOrderMark.UTF_8,
ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE,
ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE ) ) ) )
{
// use br here
} catch( Exception e)
}
Run Code Online (Sandbox Code Playgroud)
考虑一下来自 Google 的UnicodeReader,它可以为您完成所有这些工作。
Charset utf8 = Charset.forName("UTF-8"); // default if no BOM present
try (Reader r = new UnicodeReader(new FileInputStream(file), utf8)) {
....
}
Run Code Online (Sandbox Code Playgroud)
Maven 依赖:
<dependency>
<groupId>com.google.gdata</groupId>
<artifactId>core</artifactId>
<version>1.47.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
例如,让我们看一下下面的代码(用于读取包含拉丁字符和西里尔字符的文本文件):
String defaultEncoding = "UTF-16";
InputStream inputStream = new FileInputStream(new File("/temp/1.txt"));
BOMInputStream bomInputStream = new BOMInputStream(inputStream);
ByteOrderMark bom = bomInputStream.getBOM();
String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
InputStreamReader reader = new InputStreamReader(new BufferedInputStream(bomInputStream), charsetName);
int data = reader.read();
while (data != -1) {
char theChar = (char) data;
data = reader.read();
ari.add(Character.toString(theChar));
}
reader.close();
Run Code Online (Sandbox Code Playgroud)
因此,我们有一个名为“ari”的 ArrayList,其中包含文件“1.txt”中除 BOM 之外的所有字符。