编码转换:UTF-8 BOM to GBK

编码转换:UTF-8 BOM to GBK

      最近因为一个实验,需要文本文件的编码格式为GBK或者GB2312,而源数 据又是很多编码格式的,有些是GBK,有些是UTF-8,这样就不好用工具直接转,手动就更不可取了,于是打算写个程序,能够读取UTF-8的文件,更改编码后,再写入另一个文件,存为GBK格式。

      在网上看了很多例子,也查了python API,发现都不完整,原因就在于都没考虑到有BOM和无BOM两种情况。也有说用codecs.EncodedFile(...)来做的,试了很多次,无论是有BOM还是无BOM,转成GBK都失败。

      下面来看我的试验过程。

      1.无BOM的UTF-8转GBK

      首先用ultraedit新建一个文本文件,并存为UTF-8 无BOM格式,我的叫“u8.txt”,内容为“试 试 这 个”,带回车换行,并且字符间加了空格,以便定位;

      其次,写代码测试:

              import codecs

              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();

      运行查看结果:

             读取utf8无BOM的文件

      根据输出可见,第一行是4个汉字字符的UTF-8编码,每个字符占3个字节,最后跟着一个换行符;第二行是编码为GBK后打印的结果,说明编码转换没有问题;注意字符串s的内容为我手工截取的最后两个字符的字节编码,即“这 个”,对s先解码再编码成GBK后,成功输出。

      由此可知,无BOM的UTF-8转换成GBK是很容易的。

      2.有BOM的UTF-8转GBK

      首先,仍然用ultraedit新建一个文本文件,但是需要保存为UTF-8,这就是有BOM的格式,我的是“char.txt”,内容为“老 子 不 信 转 不 过 来”,也是带空格以便定位字符,仍然用上面的代码运行,结果为:

      读取UTF8带BOM

       出现错误!提示说无法对0字节处采用GBK编码,再看显示出的编码序列,发现最开头那段6个字节连在一起,但是我们的字符串分明是按空格分开的!怎么回事?!通过查wikipedia发现:

       BOM

       原来最开始的“/xef/xbb/xbf”是UTF-8的BOM!那是不是因为这个BOM才造成编码转换失败的呢?可以复制BOM后面的内容作为字符串s的内容,写代码测试,代码如下:

       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")
       运行后发现,转换成功进行,这就是说,只要能在转换前去掉BOM,那么就能转换成功。
       根据上面的心得,我写了下面的代码测试:

       代码

       代码说明:bom为读取文件前3个字节的内容,codecs.BOM_UTF8代表的就是utf8 BOM的字节编码,前面已经提到了。if语句判断是否为UTF8 BOM格式,如果是,我们就从文件的第3个字节开始读文件,以便避开BOM,然后就是转换,最后成功输出。

       结果

        代码中“注意”那行打印出字节编码,可见,字符已被转换成2 Bytes per character的GBK编码格式。

 

        结束语:这里只写了UTF8格式的,UTF16的道理也一样,只是UTF16的BOM只有两个字节,具体可见上面的BOM表示的图。总结起来说就是:UTF8转GBK本来是很容易的,因为字符都对应,只是因为有了BOM,使问题变得麻烦些,不过弄懂了原理也不复杂

转载于:https://my.oschina.net/ypimgt/blog/89598

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值