java转文件编码bom_编码转换:UTF-8 BOM to GBK
在網(wǎng)上看了很多例子,也查了python API,發(fā)現(xiàn)都不完整,原因就在于都沒考慮到有BOM和無BOM兩種情況。也有說用codecs.EncodedFile(...)來做的,試了很多次,無論是有BOM還是無BOM,轉(zhuǎn)成GBK都失敗。
下面來看我的試驗(yàn)過程。
1.無BOM的UTF-8轉(zhuǎn)GBK
首先用ultraedit新建一個文本文件,并存為UTF-8 無BOM格式,我的叫“u8.txt”,內(nèi)容為“試 試 這 個”,帶回車換行,并且字符間加了空格,以便定位;
其次,寫代碼測試:
importcodecs
f =?open("u8.txt", "r");
data = f.read();
print repr(data)
print data.decode("utf-8").encode("gbk")
s = '/xe8/xbf/x99 /xe4/xb8/xaa';
print s.decode("utf-8").encode("gbk")
f.close();
運(yùn)行查看結(jié)果:
根據(jù)輸出可見,第一行是4個漢字字符的UTF-8編碼,每個字符占3個字節(jié),最后跟著一個換行符;第二行是編碼為GBK后打印的結(jié)果,說明編碼轉(zhuǎn)換沒有問題;注意字符串s的內(nèi)容為我手工截取的最后兩個字符的字節(jié)編碼,即“這 個”,對s先解碼再編碼成GBK后,成功輸出。
由此可知,無BOM的UTF-8轉(zhuǎn)換成GBK是很容易的。
2.有BOM的UTF-8轉(zhuǎn)GBK
首先,仍然用ultraedit新建一個文本文件,但是需要保存為UTF-8,這就是有BOM的格式,我的是“char.txt”,內(nèi)容為“老 子 不 信 轉(zhuǎn) 不 過 來”,也是帶空格以便定位字符,仍然用上面的代碼運(yùn)行,結(jié)果為:
出現(xiàn)錯誤!提示說無法對0字節(jié)處采用GBK編碼,再看顯示出的編碼序列,發(fā)現(xiàn)最開頭那段6個字節(jié)連在一起,但是我們的字符串分明是按空格分開的!怎么回事?!通過查wikipedia發(fā)現(xiàn):
原來最開始的“/xef/xbb/xbf”是UTF-8的BOM!那是不是因?yàn)檫@個BOM才造成編碼轉(zhuǎn)換失敗的呢?可以復(fù)制BOM后面的內(nèi)容作為字符串s的內(nèi)容,寫代碼測試,代碼如下:
s = '/xe8/x80/x81 /xe5/xad/x90 /xe4/xb8/x8d /xe4/xbf/xa1 /xe8/xbd/xac /xe4/xb8/x8d /xe8/xbf/x87 /xe6/x9d/xa5/n'
print s.decode("utf-8").encode("gbk")
運(yùn)行后發(fā)現(xiàn),轉(zhuǎn)換成功進(jìn)行,這就是說,只要能在轉(zhuǎn)換前去掉BOM,那么就能轉(zhuǎn)換成功。
根據(jù)上面的心得,我寫了下面的代碼測試:
代碼說明:bom為讀取文件前3個字節(jié)的內(nèi)容,codecs.BOM_UTF8代表的就是utf8 BOM的字節(jié)編碼,前面已經(jīng)提到了。if語句判斷是否為UTF8 BOM格式,如果是,我們就從文件的第3個字節(jié)開始讀文件,以便避開BOM,然后就是轉(zhuǎn)換,最后成功輸出。
代碼中“注意”那行打印出字節(jié)編碼,可見,字符已被轉(zhuǎn)換成2 Bytes per character的GBK編碼格式。
結(jié)束語:這里只寫了UTF8格式的,UTF16的道理也一樣,只是UTF16的BOM只有兩個字節(jié),具體可見上面的BOM表示的圖。總結(jié)起來說就是:UTF8轉(zhuǎn)GBK本來是很容易的,因?yàn)樽址紝?yīng),只是因?yàn)橛辛薆OM,使問題變得麻煩些,不過弄懂了原理也不復(fù)雜
總結(jié)
以上是生活随笔為你收集整理的java转文件编码bom_编码转换:UTF-8 BOM to GBK的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AMD处理器,DDR4内存支持全解析
- 下一篇: java培训第一阶段测试总结_java学