我打开我的Windows,输入18,并将文件保存为utf-8编码。我知道我的文件将有一个BOM头,而我的文件是一个utf-8编码的文件(带有BOM头)。
问题是,当通过下面的代码打印该字符串时:
//str is that string read from the file using StandardCharsets.UTF_8 encoding
System.out.println(str);在窗户里:
?18但是在linux中我得到了:
18那么为什么java的行为是不同的呢?如何理解它?
发布于 2019-03-21 05:09:04
BOM是一个零宽度的空间,原则上是看不见的.
然而,窗口没有UTF-8编码,而是使用多个单字节编码之一。从字符串到输出的转换将把字符集中缺少的BOM转换成问号。
尽管如此,记事本仍将识别BOM并显示UTF-8文本.
Linux现在通常使用UTF-8,所以没有问题,在控制台也是如此.
进一步解释
在Windows中,System.out使用控制台,该控制台使用字符集/编码(例如Cp-850 ),单个字节字符集约为256个字符。缺少的很可能是ĉ或BOM字符。如果java字符串包含这些字符,则不能将它们编码到256个可用字符中的一个。因此,它们将被转换为?。
String s = ...
CharsetEncoder encoder = Charset.defaultCharset().newEncoder();
if (!encoder.canEncode(s)) {
System.out.println("A problem");
}Windows通常也运行在单个字节编码上,比如Cp-1252.再来256个字符。但是,编辑器可以处理多个编码,如果字体可以表示字符(Unicode代码点),那么一切都可以工作。
发布于 2019-03-21 05:01:18
java的行为是一样的,FileInputStream不处理bom。
在windows中,您的文件为file1,file1十六进制表示为EF BB BF 31 38。
在linux中,您的文件是file2,file 2的十六进制表示是31 38。
当你读到它们时,你会得到不同的字符串。
我建议您使用notepad++将bom文件转换为无-bom文件。
或者您可以使用BOMInputStream
https://stackoverflow.com/questions/55273476
复制相似问题