How to Read a File Line-by-Line in Go

Created
Modified

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

Related Tags

#read# #file# #line#