Buffering holds data before it is processed or sent. In Go, a buffered reader can process a file as a stream, while a buffered writer can hold a rendered response until it is safe to send. section 7.1.1 section 9.1.4
Choose the buffer around the failure you need to handle:
- For newline-delimited records, use bufio.NewScanner with bufio.ScanLines. Decode each line separately so an invalid JSON entry need not stop processing the file. section 7.1.1
- For a template that might fail during execution, render into a bytes.Buffer. Send its contents to the response writer only if execution succeeds; otherwise, return an error response. section 9.1.4
- For logs sent to a network service, channels and buffering can improve reliability. Close the connection when finished; closing also flushes its network buffer. section 7.2.1
Listing 7.4 Using bufio to read line by line
package main
import (
"bufio"
"encoding/json"
"log"
"os"
)
func main() {
file, err := os.Open("structured.log")
if err != nil {
panic(err)
}
defer file.Close()
scan := bufio.NewScanner(file) #1
scan.Split(bufio.ScanLines) #2
lineJSON := make(map[string]interface{})
for scan.Scan() { #3
if err := json.Unmarshal([]byte(scan.Text()), &lineJSON); err != n
il {
log.Println(err)
} else {
log.Println(lineJSON["level"])
}
}
}
The scanner reads a structured log one line at a time and attempts to decode each line as JSON. section 7.1.1
Listing 9.7 Buffering a template response
package main
import (
"bytes"
"fmt"
"html/template"
"io"
"net/http"
)
var t *template.Template
func init() {
t = template.Must(template.ParseFiles("./templates/simple.html"))
}
type Page struct {
Title, Content string
}
func displayPage(w http.ResponseWriter, r *http.Request) {
p := &Page{
Title: "An Example",
Content: "Have fun stormin' da castle.",
}
var b bytes.Buffer #1
err := t.Execute(&b, p) #1
if err != nil { #2
fmt.Fprint(w, "A error occured.")
return
}
b.WriteTo(w) #3
}
func main() {
http.HandleFunc("/", displayPage)
http.ListenAndServe(":8080", nil)
}
The handler executes the template into a buffer, checks for an error, then writes the completed output to the client. section 9.1.4
Buffering a template prevents a partially rendered page, but delays the response. Write directly to the response when early delivery matters and execution failures can be handled beforehand. section 9.1.4




