前兩天用 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