考虑这样的文本文件:
Some text
here.
---
More text
another line.
---
Third part of text.我想把它分成三个部分,除以---分隔符。零件应储存在地图中。
现在,不同类型的完全相同的程序。
当我使用string时,一切都很好:
KEY: 0
Some text
here.
KEY: 1
More text
another line.
KEY: 2
Third part of text.https://play.golang.org/p/IcGdoUNcTEe
当我使用[]byte时,事情会变得一团糟:
KEY: 0
Third part of teKEY: 1
Third part of text.
ne.
KEY: 2
Third part of text.https://play.golang.org/p/jqLhCrqsvOs
为什么?
方案1 (string):
func main() {
parts := parseParts([]byte(input))
for k, v := range parts {
fmt.Printf("KEY: %d\n%s", k, v)
}
}
func parseParts(input []byte) map[int]string {
parts := map[int]string{}
s := bufio.NewScanner(bytes.NewReader(input))
buf := bytes.Buffer{}
i := 0
for s.Scan() {
if s.Text() == "---" {
parts[i] = buf.String()
buf.Reset()
i++
continue
}
buf.Write(s.Bytes())
buf.WriteString("\n")
}
parts[i] = buf.String()
return parts
}方案2 ([]byte):
func main() {
parts := parseParts([]byte(input))
for k, v := range parts {
fmt.Printf("KEY: %d\n%s", k, v)
}
}
func parseParts(input []byte) map[int]string {
parts := map[int]string{}
s := bufio.NewScanner(bytes.NewReader(input))
buf := bytes.Buffer{}
i := 0
for s.Scan() {
if s.Text() == "---" {
parts[i] = buf.String()
buf.Reset()
i++
continue
}
buf.Write(s.Bytes())
buf.WriteString("\n")
}
parts[i] = buf.String()
return parts
}发布于 2018-08-22 22:43:27
在字符串版本中,
parts[i] = buf.String()每次将parts[i]设置为新字符串。在[]byte版本中,
parts[i] = buf.Bytes()每次将parts[i]设置为由相同数组支持的字节片。支持数组的内容对于所有三个切片都是相同的,但是创建时长度与长度匹配,这就是为什么所有三个切片都显示相同的内容,但在不同的地方被切断的原因。
您可以替换字节切片行。
parts[i] = buf.Bytes()就像这样:
bb := buf.Bytes()
b := make([]byte, len(bb))
copy(b, bb)
parts[i] = b以获得与字符串版本匹配的行为。但是字符串版本更容易更好地匹配您想要做的事情。
发布于 2018-08-22 22:43:11
区别在于bytes.Buffer.String复制内存,而bytes.Buffer.Bytes不复制内存。引用文档的话,
该片只能在下一次缓冲区修改之前使用(也就是说,直到下一次调用方法(如读、写、重置或截断)为止)。
https://stackoverflow.com/questions/51975902
复制相似问题