Reputation: 1379
I have:
var buffer bytes.Buffer
s := "something to do"
for i := 0; i < 10; i++ {
buffer.WriteString(s)
}
Which appends to the buffer, is it possible to write to the beginning of a buffer?
Upvotes: 7
Views: 12644
Reputation: 417692
Inserting to the beginning is not possible, see Amd's answer for a "workaround". For overwriting content at the beginning, read on.
Note that the internal byte slice Buffer.buf
is not exported, but the method Buffer.Bytes()
returns a slice sharing the same backing array as the Buffer.buf
internal slice.
This means if you create a new bytes.Buffer
by calling Bytes.NewBuffer()
, and pass this slice after reslicing it to zero length and capacity retained, you can write to the beginning of the buffer, overwriting original data of the first buffer.
See this example:
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)
Output (try it on the Go Playground):
buf: Hello World
buf: Gopher World
buf2: Gopher
Note: Using this technique, you can also overwrite content at arbitrary position, by reslicing using the desired index instead of 0
and passing the slice. For example:
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)
Output (try it on the Go Playground):
buf: Hello World
buf: Hello Gopher
buf2: Gopher
Note that the "manipulation" of the content through the slice returned by Buffer.Bytes()
may only succeed until the Buffer
is modified, after that there's a chance that Buffer
allocates a new backing array and the one you have will be "detached" (and so further modification on it will not be reflected in the original 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).
Upvotes: 6
Reputation:
Since the underlying buf
not exported from bytes.Buffer
, you may use:
buffer.WriteString("B")
s := buffer.String()
buffer.Reset()
buffer.WriteString("A")
buffer.WriteString(s)
Try this The Go Playground:
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())
}
output:
AB
Upvotes: 8