根据Scanner.scan documents
,Scan()
将扫描仪推进到下一个令牌,但这意味着什么?我发现Scanner.Text
和Scanner.Bytes
可能会有所不同,这令人费解。
此代码并不总是会导致错误,但随着文件变大,它会:
func TestScanner(t *testing.T) {
path := "/tmp/test.txt"
f, err := os.Open(path)
if err != nil {
panic(fmt.Sprint("failed to open ", path))
}
defer f.Close()
scanner := bufio.NewScanner(f)
bs := make([][]byte, 0)
for scanner.Scan() {
bs = append(bs, scanner.Bytes())
}
f, err = os.Open(path)
if err != nil {
panic(fmt.Sprint("failed to open ", path))
}
defer f.Close()
scanner = bufio.NewScanner(f)
ss := make([]string, 0)
for scanner.Scan() {
ss = append(ss, scanner.Text())
}
for i, b := range bs {
if string(b) != ss[i] {
t.Errorf("expect %s, got %s", ss[i], string(b))
}
}
}
答案 0 :(得分:3)
令牌由扫描仪split function定义。当split函数找到一个令牌或者出现错误时,Scan()会返回。
String()和Bytes()方法都返回当前标记。 String()方法returns a copy of the token。 Bytes()方法不分配内存和returns a slice,它们可能使用后续调用Scan()时覆盖的后备数组。
从字节()返回Copy the slice以避免此问题:
for scanner.Scan() {
bs = append(bs, append([]byte(nil), scanner.Bytes()...))
}