给定字符序列的hexdump 可能是ef bb bf。我说可能,因为我不得不猜测你的显示编码。
如果正确,您正在尝试将 UTF-8 编码文件 with BOM prefix 读取为 ISO-8859-X。这与您在使用 vi/vim 打开文件时没有看到这些字符的事实相一致。大多数(如果不是全部)支持 UTF-8 的文本编辑器都知道如何处理 BOM。
从 Java 中,您必须手动跳过它(虽然不知道为什么它可以在 Windows 上运行)。
另一种选择是将您的文本文件保存为 UTF-8 不带 BOM。
这已经讨论过了。例如:
由于这不是很清楚,我做了以下实验:我创建了两个文件,utf-8 编码并包含字符串 "L'élève va à l 'école." 这两个测试文件之间的唯一区别是一个具有 BOM 前缀。
然后,根据 OP 给出的代码和 Thomas Mueller 的建议,我编写了一个非常简单的 Java 应用程序来使用各种编码读取这些文件。代码如下:
public class EncodingTest {
public static String read(String file, String encoding) throws IOException {
StringBuffer fileData = new StringBuffer(1000);
/* Only difference with OP code */
/* I use *explicit* encoding while reading the file */
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file), encoding)
);
char[] buf = new char[5000];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
reader.close();
return fileData.toString();
}
public static void main(String[] args) throws IOException {
System.out.print(read("UTF-8-BOM-FILE", "UTF-8"));
System.out.print(read("UTF-8-FILE", "UTF-8"));
System.out.print(read("UTF-8-BOM-FILE", "ISO-8859-15"));
System.out.print(read("UTF-8-FILE", "ISO-8859-15"));
}
}
当我在控制台编码为 UTF8 的 Linux 系统上运行它时,我得到了以下结果:
$ java -cp bin EncodingTest
L'élève va à l'école.
L'élève va à l'école.
L'élÚve va à l'école.
L'élÚve va à l'école.
注意第三行如何以与 OP 给出的完全相同的顺序开始。那是在读取 utf8 编码文件,BOM 为 iso-8859-15。
令人惊讶的是,前两行似乎是相同的,就像 Java 神奇地删除了 BOM 一样。我想这就是 Windows 上 OP 的附加内容。
但是,仔细检查表明:
$ java -cp bin EncodingTest | hexdump -C
00000000 ef bb bf 4c 27 c3 a9 6c c3 a8 76 65 20 76 61 20 |...L'..l..ve va |
00000010 c3 a0 20 6c 27 c3 a9 63 6f 6c 65 2e 0a 4c 27 c3 |.. l'..cole..L'.|
00000020 a9 6c c3 a8 76 65 20 76 61 20 c3 a0 20 6c 27 c3 |.l..ve va .. l'.|
00000030 a9 63 6f 6c 65 2e 0a c3 af c2 bb c2 bf 4c 27 c3 |.cole........L'.|
00000040 83 c2 a9 6c c3 83 c5 a1 76 65 20 76 61 20 c3 83 |...l....ve va ..|
00000050 c2 a0 20 6c 27 c3 83 c2 a9 63 6f 6c 65 2e 0a 4c |.. l'....cole..L|
00000060 27 c3 83 c2 a9 6c c3 83 c5 a1 76 65 20 76 61 20 |'....l....ve va |
00000070 c3 83 c2 a0 20 6c 27 c3 83 c2 a9 63 6f 6c 65 2e |.... l'....cole.|
00000080 0a |.|
00000081
请注意前三个字节:BOM 已发送到输出——但我的控制台以某种方式丢弃了它们。但是,从 Java 程序的角度来看,那些存在的字节——我可能应该手动处理它们。
那么,这一切的寓意是什么? OP 确实有两个 问题:一个 BOM 前缀的 UTF8 编码文件。该文件被读取为 iso-8859-X。
Yuris,为了解决这个问题,你必须在你的 Java 程序中明确使用正确的编码,并且要么丢弃前 3 个字节或改变您的数据文件以删除 BOM。