Go言語(golang)でShiftJISのファイルをutf-8に変換する

データアナリティクス事業本部の森脇です。

Go言語で文字コードを変換するための方法について調べました。

使用するGo言語のバージョンは1.13.6です。

パッケージのインストール

文字コード変換を行うために、準標準パッケージであるgolang.org/x/textを使用します。

1
2
3
4
5
6
7
8
9
10
11
12
$ go mod init example.com/moriwaki/iconv
go: creating new go.mod: module example.com/moriwaki/iconv
$ go get -u golang.org/x/text
go: finding golang.org/x/text v0.3.2
go: downloading golang.org/x/text v0.3.2
go: extracting golang.org/x/text v0.3.2
$ cat go.mod
module example.com/moriwaki/iconv
 
go 1.13
 
require golang.org/x/text v0.3.2 // indirect

作っていく

main.goファイルを作成し、実装していきます。

変換にはgolang.org/x/text/transformを使います。

また、ShiftJISを扱うためにgolang.org/x/text/encoding/japaneseも使います。

ShiftJISからutf-8へ変換

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package main
 
import (
  "bufio"
  "io"
  "log"
  "os"
 
  "golang.org/x/text/encoding/japanese"
  "golang.org/x/text/transform"
)
 
func main() {
  // ShiftJISファイルを開く
  sjisFile, err := os.Open("./sjis.txt")
  if err != nil {
    log.Fatal(err)
  }
  defer sjisFile.Close()
 
  // ShiftJISのデコーダーを噛ませたReaderを作成する
  reader := transform.NewReader(sjisFile, japanese.ShiftJIS.NewDecoder())
 
  // 書き込み先ファイルを用意
  utf8File, err := os.Create("./utf-8.txt")
  if err != nil {
    log.Fatal(err)
  }
  defer utf8File.Close()
 
  // 書き込み
  tee := io.TeeReader(reader, utf8File)
  s := bufio.NewScanner(tee)
  for s.Scan() {
  }
  if err := s.Err(); err != nil {
    log.Fatal(err)
  }
  log.Println("done")
}

読み込み時にShiftJISをutf-8へ変換し、ファイルへ書き込みます。

実行し、結果をnkfコマンドで確認してみます。

1
2
3
4
5
6
$ nkf -g sjis.txt
Shift_JIS
$ go run main.go
2020/02/04 16:15:39 done
$ nkf -g utf-8.txt
UTF-8

うまく変換できました。

utf-8からShiftJISへ変換

逆のパターンを試してみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package main
 
import (
  "bufio"
  "io"
  "log"
  "os"
 
  "golang.org/x/text/encoding/japanese"
  "golang.org/x/text/transform"
)
 
func main() {
  // utf-8ファイルを開く
  utf8File, err := os.Open("./utf-8.txt")
  if err != nil {
    log.Fatal(err)
  }
  defer utf8File.Close()
 
  // 書き込み先ファイルを用意
  sjisFile, err := os.Create("./out-sjis.txt")
  if err != nil {
    log.Fatal(err)
  }
  defer sjisFile.Close()
 
  // ShiftJISのエンコーダーを噛ませたWriterを作成する
  writer := transform.NewWriter(sjisFile, japanese.ShiftJIS.NewEncoder())
 
  // 書き込み
  tee := io.TeeReader(utf8File, writer)
  s := bufio.NewScanner(tee)
  for s.Scan() {
  }
  if err := s.Err(); err != nil {
    log.Fatal(err)
  }
  log.Println("done")
}

実装上も逆の処理を行います。

utf-8のファイルを読み込み、書き込み時にShiftJISに変換します。

実行してみます。

1
2
3
4
5
6
$ nkf -g utf-8.txt
UTF-8
$ go run main.go
2020/02/04 16:19:33 done
$ nkf -g out-sjis.txt
Shift_JIS

こちらも正常に変換できました。

まとめ

「golang.org/x/text」パッケージを使うことで、非常に簡単に文字コード変換を行うことができました。

「golang.org/x/text/encoding/japanese」パッケージでは、ShiftJISの他にもEUC-JP, ISO-2022-JPも扱えるようです。

また、「golang.org/x/text/encoding/...」には日本語の他にも、韓国語,中国語向けのパッケージも存在していたので、こちらの言語の変換処理も簡単に行えるかもしれません。

Go言語はパッケージ構成が整っており、インターフェースも綺麗なのでファイル以外の変換も簡単に行えそうでした。

参考サイト

PRもっと安く使いたい