【Go】UTF-8でないCSVを取り扱う時の注意点
はじめに
Excel等で作られたCSVファイルは、Shift-JISでエンコードされていることが多々あります。
しかし、GoではUTF-8として扱うことが前提であるため、そのまま扱うと文字化けが起こってしまいます。
今回は、UTF-8ではないエンコード方式のCSVファイルを扱う方法を見ていきます。
この記事でわかること
- UTF-8ではないCSVファイルをそのまま扱うと起きること
- UTF-8に変換してCSVファイルを読み込む方法
UTF-8ではないCSVファイルをそのまま扱ってみる
今回はShift-JISでエンコードされたCSVファイルをそのまま扱ってみようと思います。
CSVファイルは以下のものを使います。
1,�R�c���Y,30,����
2,��؉Ԏq,25,���
# nkf -g example_sjis.csv
Shift_JIS
CSVを読み込み、レコードを標準出力するという簡単な実装を例に見ていきましょう。
func main() {
f, err := os.Open("example_sjis.csv")
if err != nil {
log.Fatal(err)
}
defer f.Close()
csvReader := csv.NewReader(f)
csvReader.FieldsPerRecord = -1
for {
record, err := csvReader.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Println(record)
}
}
実行すると、以下のように出力されます。
# go run main.go
[1 �R�c���Y 30 ����]
[2 ��؉Ԏq 25 ���]
エンコード方式が異なるため、文字化けが起こったまま出力されていることがわかります。
UTF-8に変換してCSVファイルを扱ってみる
ここでは、Shift-JISをUTF-8に変換して読み込んでみようと思います。
func main() {
f, err := os.Open("example_sjis.csv")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// CSVデータをShift-JISからUTF-8に変換するReaderを作成
reader := transform.NewReader(f, japanese.ShiftJIS.NewDecoder())
csvReader := csv.NewReader(reader)
csvReader.FieldsPerRecord = -1
for {
record, err := csvReader.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Println(record)
}
}
実行すると、以下のように出力されます。
# go run main.go
[1 山田太郎 30 東京]
[2 鈴木花子 25 大阪]
今回は、golang.org/x/text/encoding/japaneseとgolang.org/x/text/transformというパッケージとそこで定義されているメソッドを使いました。以下に、それぞれのパッケージやメソッドについて超概説を記載します。
1. golang.org/x/text/encoding/japanese
これは、日本語テキストをエンコーディングを扱うためのパッケージです。
NewDecoder()を使うことで、Shift_JIS・EUC-JP・ISO-2022-JPなどをUTF-8に変換するよう指定することができます。
2. golang.org/x/text/transform
これは、テキストデータの変換処理を行うための基盤パッケージです。
NewReader()を使うことで、指定したTransformer(変換ルール)を使って、io.Readerから読み込むデータを変換しながら返すReaderを生成することができます。
まとめ
今回はUTF-8ではないCSVファイルをUTF-8に変換して読み込む方法について見ていきました。
ポイントを整理すると以下の通りです。
- Goの文字列は
UTF-8前提であるため、Shift_JISやEUC-JPなどの文字コードのまま読み込むと文字化けが起こる -
golang.org/x/text/encoding/japaneseのNewDecoder()を使うことで、Shift_JISなどの日本語文字コードをUTF-8に変換できる -
golang.org/x/text/transformのNewReader()を使うことで、ファイルやストリームを読み込む際に変換処理を適用したReaderを作れる - 変換済みの
Readerをcsv.NewReader()に渡すことで、CSVデータを正しくUTF-8として解析・処理できる
この方法を使えば、Shift_JISなどの非UTF-8エンコードのCSVファイルも、Goで安全に読み込み・処理できるようになります。Excelなどで作成されたCSVを扱う際には、文字コード変換を意識して処理することが重要です。
Discussion