前两天用 GO 写一个网站的爬虫练手,但爬下来的内容是乱码的,一看原来该网站是 GBK 编码的,而 GO 中默认编码是 UTF-8 的,因此会致使非 UTF-8 的内容是乱码的。git
因而我去找了一下 GO 的转码库,主要有 mahonia、iconv-go、和官方的 golang.org/x/text 这三个库用的比较多。github
对这三个库都使用了一下,发现都不是很满意。下面看一下这三个库的 GBK 转 UTF-8。golang
package main import "fmt" import "github.com/axgle/mahonia" func main() { testBytes := []byte{0xC4, 0xE3, 0xBA, 0xC3, 0xA3, 0xAC, 0xCA, 0xC0, 0xBD, 0xE7, 0xA3, 0xA1} testStr := string(testBytes) enc := mahonia.NewDecoder("gbk") res := enc.ConvertString(testStr) fmt.Println(res) // 你好,世界! } 复制代码
package main import ( "fmt" "github.com/axgle/mahonia" iconv "github.com/djimenez/iconv-go" ) func main() { testBytes := []byte{0xC4, 0xE3, 0xBA, 0xC3, 0xA3, 0xAC, 0xCA, 0xC0, 0xBD, 0xE7, 0xA3, 0xA1} var res []byte iconv.Convert(testBytes, res, "GBK", "UTF-8") fmt.Printf(string(res)) // 你好,世界! } 复制代码
package main import ( "bytes" "fmt" "io/ioutil" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" ) func main() { testBytes := []byte{0xC4, 0xE3, 0xBA, 0xC3, 0xA3, 0xAC, 0xCA, 0xC0, 0xBD, 0xE7, 0xA3, 0xA1} decoder := simplifiedchinese.GBK.NewDecoder() reader := transform.NewReader(bytes.NewReader(testBytes), decoder) res, _ := ioutil.ReadAll(reader) fmt.Printf(string(res)) // 你好,世界! } 复制代码
上面就是这三个库的基本使用,能够发现这三个库都有一些问题:markdown
string
类型的值,而咱们在 GO 中处理数据不少时候都是 []byte
或者 io.Reader
类型的,这个就比较局限了。string
、[]byte
和 io.Reader
类型的数据,但底层是对 C 的 iconv 库的封装,在各类环境下都会出现问题,编译时出错也很差定位,我以前有几回都没装成功:(。我思索了一下,感受链式调用是一个不错的解决方案,因而造了一个轮子,叫作 transcode,下面看一下使用方式:oop
package main import ( "fmt" "github.com/piex/transcode" ) func main() { testBytes := []byte{0xC4, 0xE3, 0xBA, 0xC3, 0xA3, 0xAC, 0xCA, 0xC0, 0xBD, 0xE7, 0xA3, 0xA1} res := transcode.FromByteArray(testBytes).Decode("GBK").ToString() fmt.Printf(res) // 你好,世界 } 复制代码
package main import ( "bytes" "fmt" "github.com/piex/transcode" ) func main() { testBytes := []byte{0xC4, 0xE3, 0xBA, 0xC3, 0xA3, 0xAC, 0xCA, 0xC0, 0xBD, 0xE7, 0xA3, 0xA1} testStr := "你好,世界!" res := transcode.FromString(testStr).Encode("GBK").ToByteArray() fmt.Println(bytes.Equal(res, testBytes)) // true } 复制代码
这个库底层是对 golang.org/x/text 转码相关的 API 的一个封装,这个是官方的库,仍是值得承认的,知识 API 太难用了,因此对这个库进行了一个封装,目前支持 string
和 []byte
数据类型的输入输出。网站
这里使用了链式调用,主要是在最后把结构体返回就能够了。而后对 ToString
和 ToByteArray
这两个方法作另外的处理。编码
仓库地址:github.com/piex/transc…,你们能够看一下源码,还很简陋,后面还会添加对 io.Reader
类型的支持,有兴趣的能够 pr。spa