前两天用 GO 写一个网站的爬虫练手,但爬下来的内容是乱码的,一看原来该网站是 GBK 编码的,而 GO 中默认编码是 UTF-8 的,所以会导致非 UTF-8 的内容是乱码的。
于是我去找了一下 GO 的转码库,主要有 mahonia、iconv-go、和官方的 golang.org/x/text 这三个库用的比较多。
对这三个库都使用了一下,发现都不是很满意。下面看一下这三个库的 GBK 转 UTF-8。
- mahonia
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) // 你好,世界!
}
- iconv-go
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)) // 你好,世界!
}
- golang.org/x/text
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)) // 你好,世界!
}
上面就是这三个库的基本使用,可以发现这三个库都有一些问题:
- mahonia 的 API 是最简单的,但是只能输入输出
string
类型的值,而我们在 GO 中处理数据很多时候都是[]byte
或者io.Reader
类型的,这个就比较局限了。 - iconv-go 可以读取
string
、[]byte
和io.Reader
类型的数据,但底层是对 C 的 iconv 库的封装,在各种环境下都会出现问题,编译时出错也不好定位,我之前有几次都没装成功:(。 - golang.org/x/text 这是官方提供的库,但是 API 太繁琐了,pass。
transcode
我思索了一下,感觉链式调用是一个不错的解决方案,于是造了一个轮子,叫做 transcode,下面看一下使用方式:
- GBK 转 UTF-8
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) // 你好,世界
}
- UTF-8 转 GBK
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。
今天的文章GO 的链式调用写一个转码库分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/22391.html