关于go:写到Golang缓冲区的开头?


Write to beginning of the buffer in Golang?

我有:

1
2
3
4
5
var buffer bytes.Buffer
s :="something to do"
for i := 0; i < 10; i++ {
   buffer.WriteString(s)
}

哪个附加到缓冲区,是否可以写入缓冲区的开头?


由于基础buf不是从bytes.Buffer出口的,您可以使用:

1
2
3
4
5
buffer.WriteString("B")
s := buffer.String()
buffer.Reset()
buffer.WriteString("A")
buffer.WriteString(s)

试试这个游乐场:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
   "bytes"
   "fmt"
)

func main() {
    var buffer bytes.Buffer
    buffer.WriteString("B")
    s := buffer.String()
    buffer.Reset()
    buffer.WriteString("A" + s)
    fmt.Println(buffer.String())
}

输出:

1
AB

插入到开头是不可能的,见AMD的"解决方法"的答案。要在开始时覆盖内容,请继续阅读。

注意,内部字节片Buffer.buf没有导出,但是方法Buffer.Bytes()返回一个与Buffer.buf内部片共享相同的后备数组的片。

这意味着,如果通过调用Bytes.NewBuffer()创建一个新的bytes.Buffer,并在重新将该片复制到零长度和保留容量后传递该片,则可以写入缓冲区的开头,覆盖第一个缓冲区的原始数据。

请参见此示例:

1
2
3
4
5
6
7
8
buf := &bytes.Buffer{}
buf.WriteString("Hello  World")
fmt.Println("buf:", buf)

buf2 := bytes.NewBuffer(buf.Bytes()[:0])
buf2.WriteString("Gopher")
fmt.Println("buf:", buf)
fmt.Println("buf2:", buf2)

输出(在游乐场上尝试):

1
2
3
buf: Hello  World
buf: Gopher World
buf2: Gopher

注意:使用此技术,您还可以覆盖任意位置的内容,方法是使用所需的索引而不是0重新进行擦除并传递切片。例如:

1
2
3
4
5
6
7
8
buf := &bytes.Buffer{}
buf.WriteString("Hello  World")
fmt.Println("buf:", buf)

buf2 := bytes.NewBuffer(buf.Bytes()[6:6]) // Start after the"Hello"
buf2.WriteString("Gopher")
fmt.Println("buf:", buf)
fmt.Println("buf2:", buf2)

输出(在游乐场上尝试):

1
2
3
buf: Hello  World
buf: Hello Gopher
buf2: Gopher

请注意,通过Buffer.Bytes()返回的切片对内容进行"操作"可能只有在Buffer被修改之后才能成功,在这之后,Buffer有可能分配一个新的支持数组,而您已经"分离"的支持数组(因此对它的进一步修改不会反映在原来的Buffer中):

The slice is valid for use only until the next buffer modification (that is, only until the next call to a method like Read, Write, Reset, or Truncate).