文件编码格式的转换之GB2312转UTF-8 Without BOM

中文区最常使用的两种文件编码格式:
Chinese Simplified(GB2312) - Codepage 936
Unicode(UTF-8 without signature) - Codepage 65001
也就是中文文件编码格式和国际通用文件编码格式(Unicode使用UTF-8方式实现的文件编码格式)。

我们都知道,非常不幸的,GB2312与UTF-8互相不通用,在不知道文件编码格式的情况下,使用特定编码格式打开另一种编码格式的文件,基本上只能看到乱码。
为什么有的时候看到的不是乱码?
在低128,它们的编码格式是相同的,所以这部分——其实主要是英文、数字和英文符号,不会显示为乱码。
为什么我用浏览器看网页时,在不知道编码格式的情况下,并没有看到乱码网页?
因为浏览器识别了网页的编码格式,并进行了正确的解码。
换句话说,有些情况下,浏览器也会把网页显示成乱码,因为浏览器也会解码错误,只是这种BUG现在已经比较少了,不是还有程序员嘛~

GB2312在记事本(和其他一些软件,比如:Beyond Compare)中一般显示为ANSI,表示这个文件使用了GB2312编码格式。
有可能显示的是ANSI,但是,实际上不是GB2312编码格式吗?
有可能。
所以,是充分非必要条件,就是这个问题反之不一定成立。

我们都知道,UTF-8有BOM头,这件事,是微软自己搞出来的,所以,基本上,为了通用(和跟网络有关的功能),UTF-8都是不带BOM头的。
微软自己不知道,UTF-8有BOM头,这件事,其实在软件应用技术开发领域里,口碑非常差吗?
微软当然知道,UTF-8有BOM头,这件事,做软件应用开发的程序员都讨厌这个东西,因为“UTF-8有BOM头,根本没什么用”。
微软为什么不去掉这个编码设定呢?
其实是历史的原因,和需要兼容之前的程序。
微软最初设计,UTF-8有BOM头,这件事,当时其实是非常明智的!因为隐含的在文件头部写入3字节的文件信息,可以大大方便判断“这个文件是什么编码格式”这个问题。
说到底,后来大家包括标准化组织ISO,另外搞出了Unicode这套“终极标准”——大而全,可以通过查表判断文件的编码格式,确实是更方便,因为不用瞒着用户在文件头部写入3字节的文件信息。
可是微软实施,UTF-8有BOM头,这件事,至少已经过去5年(甚至都不止),“终极标准”当然好,可也是看到了先贤们在实际应用中的种种问题,采用了更优秀的方案。
吃水不忘打井人,微软并没有做错~
ISO的Unicode标准其实并不硬气,如果Unicode是先出生的,可能编码格式和转换方法会更混乱~

GB2312转UTF-8,有哪些方法?
方法非常多:
使用Windows的记事本程序,打开GB2312文件,另存为,编码选UTF-8,即可。
同理,专业一点的Visual Studio 2019(VS2019)也可以使用Advanced Save Options,把GB2312文件转为UTF-8。
如果会写点代码,使用PYTHON的.decode( "GB2312"),.encode("UTF-8"),应该也可以把GB2312文件转为UTF-8。
不过,很多人机器上,其实没装PYTHON,理论上,在Windows上批处理命令,是最方便的,因为不用安装,不过批处理命令好像不能实现编码格式转换这个工作(我查下来,觉得挺奇怪的),最后使用VBS实现的:
1.
创建ConverFile_From_GB2312_To_UTF8WithoutBOM.vbs,内容如下:

Option Explicit

Private Const adReadAll = -1
Private Const adSaveCreateOverWrite = 2
Private Const adTypeBinary = 1
Private Const adTypeText = 2
Private Const adWriteChar = 0

Private Sub GB2312_To_UTF8WithBOM(ByVal GB2312FName, ByVal UTF8FName)
    Dim strText

    With CreateObject("ADODB.Stream")
        .Open
        .Type = adTypeBinary
        .LoadFromFile GB2312FName
        .Type = adTypeText
        .Charset = "GB2312"
        strText = .ReadText(adReadAll)
        .Position = 0
        .SetEOS
        .Charset = "UTF-8"
        .WriteText strText, adWriteChar
        .SaveToFile UTF8FName, adSaveCreateOverWrite
        .Close
    End With
End Sub

Private Sub SaveUTF8WithoutBOM(ByVal UTF8FName)
    Dim UTFWithBOMStream: Set UTFWithBOMStream = CreateObject("ADODB.Stream")
    Dim UTFWithoutBOMStream: Set UTFWithoutBOMStream = CreateObject("ADODB.Stream")

    UTFWithBOMStream.Open
    UTFWithBOMStream.Type = adTypeBinary

    UTFWithoutBOMStream.Open
    UTFWithoutBOMStream.Type = adTypeBinary

    UTFWithBOMStream.LoadFromFile UTF8FName
    UTFWithBOMStream.Position = 3 'skip BOM 'Strips BOM (first 3 bytes)
    UTFWithBOMStream.CopyTo UTFWithoutBOMStream

    UTFWithoutBOMStream.SaveToFile UTF8FName, adSaveCreateOverWrite
    UTFWithoutBOMStream.Flush
    UTFWithoutBOMStream.Close
End Sub

GB2312_To_UTF8WithBOM WScript.Arguments(0), WScript.Arguments(1)
SaveUTF8WithoutBOM WScript.Arguments(1)

2.
创建ConverFile_From_GB2312_To_UTF8WithoutBOM.bat,内容如下:

ConverFile_From_GB2312_To_UTF8WithoutBOM.vbs Table1_GB2312.csv Table1_UTF8WithoutBOM.csv

从Table1_GB2312.csv生成了Table1_UTF8WithoutBOM.csv,可以看到把GB2312文件转为UTF-8 Without BOM编码格式了。
当然,也可以直接转原表,即覆盖原表Table1_GB2312.csv。

参考:
a.
《Echo UTF-8 characters in windows batch》
https://stackoverflow.com/questions/11962172/echo-utf-8-characters-in-windows-batch

b.
《windows 控制台cmd乱码的解决办法 chcp 65001》
https://blog.csdn.net/hnlgzb/article/details/81911824

c.
《教你怎么用VBScript(VBS)写一个HelloWorld》
https://jingyan.baidu.com/article/a378c960ef0b1db329283042.html

d.
《How to convert a batch file stored in utf-8 to something that works via another batch file and run it》
https://stackoverflow.com/questions/13130214/how-to-convert-a-batch-file-stored-in-utf-8-to-something-that-works-via-another

e.
《Save text file UTF8 without BOM encoded》
https://social.msdn.microsoft.com/Forums/en-US/6d5d4f21-865a-4280-abef-210b6675abb9/save-text-file-utf8-without-bom-encoded?forum=isvvba

f.
《VBA : save a file with UTF-8 without BOM》
https://stackoverflow.com/questions/31435662/vba-save-a-file-with-utf-8-without-bom

g.
《VBS处理UTF-8文本之ADODB.stream》
https://blog.csdn.net/chuhe163/article/details/103549144?utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase
 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
The error message "'utf-8' codec can't decode byte 0xc4 in position 0: invalid continuation byte" suggests that there is an issue with decoding a byte sequence as UTF-8 when working with a shapefile using the shapefile library. This error can occur if the shapefile contains non-UTF-8 characters or is encoded in a different encoding that is not compatible with UTF-8. The shapefile library assumes UTF-8 encoding by default when reading attribute data from the .dbf file. To resolve this issue, you can try the following steps: 1. Specify the correct encoding: If you know the encoding of the shapefile, you can specify it explicitly when reading the attribute data. For example, if the shapefile is encoded in Latin-1, you can use the `latin1` encoding: ```python import shapefile with shapefile.Reader("your_shapefile.shp", encoding='latin1') as shp: # Access the attribute data attributes = shp.records() ``` 2. Handle non-UTF-8 characters: If the shapefile contains non-UTF-8 characters, you may need to handle them separately. You can try using a different encoding or apply error handling mechanisms to handle the decoding errors. For example, you can use the `errors='replace'` parameter to replace invalid bytes with a placeholder character: ```python import shapefile with shapefile.Reader("your_shapefile.shp", encoding='utf-8', errors='replace') as shp: # Access the attribute data attributes = shp.records() ``` By specifying the correct encoding or using appropriate error handling mechanisms, you should be able to read the attribute data from the shapefile without encountering the decoding error.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值