How to Read a File Line-by-Line in Go
Using bufio.Scanner Function
Scanner provides a convenient interface for reading data such as a file of newline-delimited lines of text. The ones that are currently implemented are:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
f, err := os.Open("file.txt")
if err != nil {
// panic()
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
One Two
There is one caveat: Scanner will error with lines longer than 65536 characters. If you know your line length is greater than 64K, use the Buffer() method to increase the scanner's capacity:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
f, err := os.Open("file.txt")
if err != nil {
// panic()
}
defer f.Close()
scanner := bufio.NewScanner(f)
const max int = 1024
buf := make([]byte, max)
scanner.Buffer(buf, max)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
One Two
Using bufio.ReadString Function
ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter. If ReadString encounters an error before finding a delimiter, it returns the data read before the error and the error itself (often io.EOF). ReadString returns err != nil if and only if the returned data does not end in delim. For simple uses, a Scanner may be more convenient. For example,
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
f, err := os.Open("file.txt")
if err != nil {
// panic()
}
defer f.Close()
rd := bufio.NewReader(f)
for {
// 0x0A separator = newline
line, err := rd.ReadString(10)
// Trim
// line = strings.TrimSpace(line)
fmt.Println(line)
if err != nil {
if err == io.EOF {
break
}
// panic() return error
}
} // End for
}
One Two