簡體   English   中英

使用BOM表字符串處理utf-8時java的行為不一致

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM