Go では、ファイルを 1 行ずつstr
's または[]rune
's に読み込みたいと考えています。
ファイルは UTF-8 でエンコードする必要がありますが、私のプログラムはそれを信頼すべきではありません。無効な UTF-8 が含まれている場合は、エラーを適切に処理したいと考えています。
はありますがbytes.Runes(s []byte) []rune
、エラー戻り値はありません。無効な UTF-8 に遭遇するとパニックになりますか?
Go では、ファイルを 1 行ずつstr
's または[]rune
's に読み込みたいと考えています。
ファイルは UTF-8 でエンコードする必要がありますが、私のプログラムはそれを信頼すべきではありません。無効な UTF-8 が含まれている場合は、エラーを適切に処理したいと考えています。
はありますがbytes.Runes(s []byte) []rune
、エラー戻り値はありません。無効な UTF-8 に遭遇するとパニックになりますか?
例えば、
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"strings"
"unicode/utf8"
)
func main() {
tFile := "text.txt"
t := []byte{'\xFF', '\n'}
ioutil.WriteFile(tFile, t, 0666)
f, err := os.Open(tFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer f.Close()
r := bufio.NewReader(f)
s, err := r.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(1)
}
s = strings.TrimRight(s, "\n")
fmt.Println(t, s, []byte(s))
if !utf8.ValidString(s) {
fmt.Println("!utf8.ValidString")
}
}
出力:
[255 10] � [255]
!utf8.ValidString
例えば:
import (
"io/ioutil"
"log"
"unicode/utf8"
)
// ...
buf, err := ioutil.ReadAll(fname)
if error != nil {
log.Fatal(err)
}
size := 0
for start := 0; start < len(buf); start += size {
var r rune
if r, size = utf8.DecodeRune(buf[start:]); r == utf8.RuneError {
log.Fatalf("invalid utf8 encoding at ofs %d", start)
}
}
utf8.DecodeRune godocs:
DecodeRune は、最初の UTF-8 エンコーディングを p でアンパックし、ルーンとその幅をバイト単位で返します。エンコーディングが無効な場合、(RuneError, 1) が返されます。これは正しい UTF-8 では不可能な結果です。