如何在Go中将编码转换为UTF-8?

时间:2015-09-11 07:58:20

标签: unicode go

我正在开展一个项目,我需要将文本从编码(例如Windows-1256阿拉伯语)转换为UTF-8。

我如何在Go中执行此操作?

3 个答案:

答案 0 :(得分:13)

您可以使用the encoding package,其中包括对包含golang.org/x/text/encoding/charmap的Windows-1256的支持(在下面的示例中,导入此包并使用charmap.Windows1256代替japanese.ShiftJIS )。

这是一个简短的例子,它将日语UTF-8字符串编码为ShiftJIS编码,然后将ShiftJIS字符串解码回UTF-8。不幸的是,它在操场上不起作用,因为操场上没有“x”包。

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "strings"

    "golang.org/x/text/encoding/japanese"
    "golang.org/x/text/transform"
)

func main() {
    // the string we want to transform
    s := "今日は"
    fmt.Println(s)

    // --- Encoding: convert s from UTF-8 to ShiftJIS 
    // declare a bytes.Buffer b and an encoder which will write into this buffer
    var b bytes.Buffer
    wInUTF8 := transform.NewWriter(&b, japanese.ShiftJIS.NewEncoder())
    // encode our string
    wInUTF8.Write([]byte(s))
    wInUTF8.Close()
    // print the encoded bytes
    fmt.Printf("%#v\n", b)
    encS := b.String()
    fmt.Println(encS)

    // --- Decoding: convert encS from ShiftJIS to UTF8
    // declare a decoder which reads from the string we have just encoded
    rInUTF8 := transform.NewReader(strings.NewReader(encS), japanese.ShiftJIS.NewDecoder())
    // decode our string
    decBytes, _ := ioutil.ReadAll(rInUTF8)
    decS := string(decBytes)
    fmt.Println(decS)
}

日本StackOverflow网站上有一个更完整的例子。该文本是日文,但代码应该是不言自明的:https://ja.stackoverflow.com/questions/6120

答案 1 :(得分:1)

我签出了here文档,然后想出了一种将字节数组转换为UTF-8(或从UTF-8转换为字节)的方法。

到目前为止,我很难过的是,我还没有找到一个允许使用语言环境的接口。而是可能的方法仅限于预定义的编码集。

就我而言,我需要将UTF-16(确实有USC-2数据,但它仍然可以工作)转换为UTF-8。为此,我需要检查BOM,然后进行转换:

bom := buf[0] + buf[1] * 256
if bom == 0xFEFF {
    enc = unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
} else if bom == 0xFFFE {
    enc = unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM)
} else {
    return Error("BOM missing")
}

e := enc.NewDecoder()

// convert USC-2 (LE or BE) to UTF-8
utf8 := e.Bytes(buf[2:])

不幸的是,我必须使用“忽略”物料清单,因为在我的情况下,应该禁止它超过第一个字符。但这对于我的情况已经足够接近了。这些功能在几个地方都提到过,但在实践中没有显示。

答案 2 :(得分:0)

我为自己制作了一个工具,也许您可​​以从中借用一些想法:)

https://github.com/gonejack/transcode

这是关键代码:

getDownloadStatus()
            .zipWith(Observable.interval(500, TimeUnit.MILLISECONDS), (status, interval) -> (String) status)
            .repeat()
            .distinctUntilChanged()
            .doOnNext(status -> ...). //some other operators