retlat's blog

Golang で UTF-8 BOM 付きの CSV を読む

お仕事で UTF-8 の CSV を Go で読む機会があったんですが、中を見たら BOM があるファイルでした
これを何も考えずに encoding/csv で読んでみたらエラーになるんですね
実際には要件のおかげで雑に対処したけど、 BOM の有無にかかわらず読むってどうしたら良いのかなと遊んでみました

ドキュメント には RFC 4180 に書いてある CSV をサポートしていると書いてあって、 このフォーマットは BOM について書いていないので知る必要がないと issue に書いてありました
そりゃそうだってことで Seek の位置を調整してから Reader に渡すようにしてみたらちゃんと読めました

愚直にしか書けないからか頭の中がそのまま記述されるみたいで Go は書いてて気持ち良い

package main

import (
	"encoding/csv"
	"log"
	"os"
)

func main() {
	f, err := os.Open("sample.csv")
	if err != nil {
		log.Fatalln("Open failed", err)
	}

	b := make([]byte, 3)
	_, err = f.Read(b)
	if err != nil {
		log.Fatalln("Read failed", err)
	}

	if !(b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xEF) {
		f.Seek(0, os.SEEK_SET)
	}

	r := csv.NewReader(f)
	rs, err := r.ReadAll()
	if err != nil {
		log.Fatalln("CSV Reader read failed", err)
	}

	log.Printf("%v\n", rs)
}