[英]java's inconsistent behavior when handling a utf-8 with BOM string
我打開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);
在Windows中,我得到了:
?18
但是在Linux中,我得到了:
18
那么,為什么Java的行為不同? 怎么理解呢?
BOM是零寬度的空間,因此原則上不可見。
但是,Window沒有UTF-8編碼,但是使用許多單字節編碼之一。 從字符串到輸出的轉換會將字符集中缺少的BOM變成問號。
記事本仍然可以識別BOM並顯示UTF-8文本。
如今的Linux通常使用UTF-8,因此在控制台中也沒有問題。
進一步說明
在Windows上, System.out
使用控制台,例如,該控制台將Cp-850(約256個字符的單字節字符集)用作字符集/編碼。 可能是ĉ
或BOM字符丟失。 如果java字符串包含這些字符,則不能將它們編碼為256個可用字符之一。 因此,它們將被轉換為?
。
使用CharsetEncoder :
String s = ...
CharsetEncoder encoder = Charset.defaultCharset().newEncoder();
if (!encoder.canEncode(s)) {
System.out.println("A problem");
}
Windows通常也以單字節編碼運行,例如Cp-1252。 再次為256個字符。 但是,編輯器可能會處理幾種編碼,如果字體可以表示字符(Unicode代碼點),則一切正常。
java的行為是相同的, FileInputStream
不處理bom。
在Windows中,文件為file1
,file1十六進制為EF BB BF 31 38
在linux中,您的文件為file2
,file2的十六進制為31 38
當您閱讀它們時,會得到不同的字符串。
我建議您使用記事本++將BOM文件轉換為無BOM文件。
或者您可以使用BOMInputStream
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.