通常的辦法,是讀取檔案的前幾個位元組,很多文字檔是在頭部用幾個位元組(BOM,Byte Order Mark)來標識文字檔的編碼類別型,比如:
UNICODE(little endian): FFFE
Unicode(big endian): FEFF
UTF-8:EFBBBF
等等。
直接先測試。寫一段程式(來源程式在下面),從本地找一個UTF-8編碼的檔案裡讀前幾個位元組,查看16進位的結果,-_-! 讀出來的直接是第一個字元,沒有所謂的BOM(EFBBBF,把FEFF按UCS到UTF-8的轉換可得到)頭,換另外一些檔案,都找不到檔案所謂的BOM頭,但用UE開啟看16進位編碼確實能看到(UTF-8編碼的檔案顯示FFFE),不解!
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(absolute_file_path));
int p = (bis.read() << 8) + bis.read();
bis.close();
System.out.println(Integer.toHexString(p));
各種測試,大半天,發現用notepad++開啟檔案,菜單中 格式-->以UTF-8格式編碼,儲存。運行程式,BOM頭讀出來了,如果在格式中選擇以UTF-8 無BOM格式編碼,就讀不出來BOM頭。
但是用UE十六進位編碼查看,卻又能看到檔案頭的FFFE兩個位元組(UE內部的自動轉換,所以看到的不是EFBBBF,不要被這個誤導)。
這是什麼問題?看樣子只能解釋為UE會根據檔案的內容<不光是BOM頭>,來判斷檔案內容是否是UTF-8編碼。查看UE的設定裡有一項-->自動檢測 UTF-8檔案,設定為OFF,再用UE十六進位查看,能看到UTF-8的BOM頭了,但是如果有非ascii的字元,顯示就有問題了!看樣子,UE不會僅根據BOM頭去判斷檔案是否是UTF-8類型???
問題:用nodepad++開啟一個UTF-8的文字檔,選擇以UTF-8 無BOM格式編碼,程式就讀不出來BOM頭了,但是用UE開啟十六進位編輯,又能看到了BOM頭,為什嗎?
解釋:UE是根據檔案內容判斷檔案編碼格式?在以十六進位方式顯示檔案內容時,會在頭部加上BOM頭?用notepad開啟該檔案,選擇另存新檔,也能看到檔案是以UTF-8
格式編碼,難道Notepad++是監測檔案內容來判斷檔案格式?而不是傳說中的根據BOM頭?
或者另外一種解釋:測試的JAVA代碼,從stream讀位元組,會忽略BOM頭?但是用notepad++選擇以UTF-8格式編碼時,會確實能讀出來BOM頭,所以代碼會忽略BOM頭這
個結論應該不成立
看樣子是第一種解釋要合理一點了。如果有朋友有更合理的解釋,歡迎提出!
參考:http://baike.baidu.com/view/414935.htm
http://zh.wikipedia.org/wiki/UTF-8