使用Golang进行字符编码转换

关于文字编码转换,有很多文章散落在各处,但感觉有点旧,所以我将其作为备忘录写下来。

使用Go语言编码字符。

在Go语言中,默认的Unicode是采用的。作为字符单位的rune应该是int32,可能相当于UTF-32,并且在代码中的字符编码也是UTF-8(参考”Part 4″)。

因此,如果需要处理除UTF-8以外的字符编码,需要进行某种转换处理。为此,可以使用transform包。此外,关于编码也有各种选项,对于日语来说,可以使用encoding/japanese包。encoding/japanese包可以处理Shift-JIS、EUC-JP和ISO-2022-JP编码。

// All is a list of all defined encodings in this package.
var All = []encoding.Encoding{EUCJP, ISO2022JP, ShiftJIS}

包裹安装

如果只需要日语,只需运行 go get golang.org/x/text/encoding/japanese,就会安装所有需要的内容。

C:>go get -v golang.org/x/text/encoding/japanese
Fetching https://golang.org/x/text/encoding/japanese?go-get=1
Parsing meta tags from https://golang.org/x/text/encoding/japanese?go-get=1 (status code 200)
get "golang.org/x/text/encoding/japanese": found meta tag main.metaImport{Prefix:"golang.org/x/text", VCS:"git", RepoRoot:"https://go.googlesource.com/text"} at https://golang.org/x/text/encoding/japanese?go-get=1
get "golang.org/x/text/encoding/japanese": verifying non-authoritative meta tag
Fetching https://golang.org/x/text?go-get=1
Parsing meta tags from https://golang.org/x/text?go-get=1 (status code 200)
golang.org/x/text (download)
golang.org/x/text/transform
golang.org/x/text/encoding/internal/identifier
golang.org/x/text/encoding
golang.org/x/text/encoding/internal
golang.org/x/text/encoding/japanese

过去,包的位置是 code.google.com/p/go.text/transform 和 code.google.com/p/go.text/encoding/japanese,但是请注意,这个存储库现在已经不存在了。

转换逻辑(示例代码)

以下是转换逻辑的示例。

package main

import (
    "bufio"
    "fmt"
    "io"

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

//Conversion
func Conversion(inStream io.Reader, outStream io.Writer) error {
    //read from stream (Shift-JIS to UTF-8)
    scanner := bufio.NewScanner(transform.NewReader(inStream, japanese.ShiftJIS.NewDecoder()))
    list := make([]string, 0)
    for scanner.Scan() {
        list = append(list, scanner.Text())
    }
    if err := scanner.Err(); err != nil {
        return err
    }
    //write to stream (UTF-8 to EUC-JP)
    writer := bufio.NewWriter(transform.NewWriter(outStream, japanese.EUCJP.NewEncoder()))
    for _, line := range list {
        _, err = fmt.Fprintln(writer, line)
        if err != nil {
            return err
        }
    }
    return writer.Flush()
}

你能理解通过 Shift-JIS(解码器)→ UTF-8(编码器)→ EUC-JP 这个步骤进行转换的意思吗?

文字编码转换应当作为流处理进行。示例代码假设以文本文件为对象,但只要能处理流,它应当适用于除文件外的其他用途。

请提供一个用于读取并转换整个文件的代码示例,通过评论进行提供。请参考。

    ShiftJIS -> EUC-JP by golang

关于文字编码转换的注意事项

Shift-JIS/EUC-JP 和 UTF-8/32 有不同的基础字符集(并非字符编码)。Shift-JIS/EUC-JP 的字符集基本上是 JIS 标准,而 UTF-8/32 是 Unicode,所以它们之间是不对称的关系。因此,在进行像这次的跨越不同字符集的转换时可能会导致转换结果不正确。

进一步令人困扰的是,由于历史因素(真是个方便的词汇w),Shift-JIS和EUC-JP的实现存在多种变体,这也可能导致实现之间的差异成为问题。

进一步说,通用机型往往采用旧的JIS加外字的构成,如果要满足这种需求,只有开发独特的转换逻辑才行。

另一种转换逻辑方案

如果之前提到的方法无法成功转换,还可以考虑使用djimenez/iconv-go包。然而,构建djimenez/iconv-go包需要libiconv和glibc(在交叉环境中要注意)。使用此包可以实现类似于iconv的处理。

我看到有一些人介绍 mahonia 作为另一个转换包,但根据文档显示,它已被标注为 DEPRECATED 并且无法使用。而且连仓库都无法访问。

收藏夹

    • golang – Go言語で文字コード変換 – Qiita

 

    • go – Goで[]byteをshift-jisの文字列に変換する – スタック・オーバーフロー

 

    • GO言語で文字コードを扱うライブラリの使用例 – Qiita

 

    Golangで文字コード判定 – Qiita
广告
将在 10 秒后关闭
bannerAds