Go - Read File Line by Line



In golang, there are various internal packages such as bufio, os, and io that can be used for reading the content of a file line by line. The bufio and os packages are used for opening and scanning the file using os.Open and bufio.NewScanner functions. The io package provides ioutil.ReadFile to read the file from the given destination and then use the strings package to display it in the output.

Method 1: Using bufio and os package

In this illustration, bufio.NewScanner is used to read line by line content and os.Open is used to open the file. As long as there is a line to read, the scan method returns true. The currently read line is returned by text. When the function returns, the file will be closed using the defer statement.

Syntax

os.Open

This function is a part of the os package. It is used to open a file for reading. It takes one input, i.e., the filename to be opened.

bufio.NewScanner

This function is a part of the bufio package. It is used to create a scanner object to read the data from the file.

Algorithm

  • Step 1 Create a package main and declare fmt (format package), bufio, and os packages in the program where main produces executable codes and fmt helps in formatting input and output.

  • Step 2 Create a main function and open the file whose content is to be read using os.Open function from the os package.

  • Step 3 If an error occurs while opening the file, print the error on the console and return.

  • Step 4 Close the opened file using defer keyword and close function.

  • Step 5 Create a bufio.NewScanner object with the file as an argument and read the contents line by line by iterating through the lines of the file.

  • Step 6 The condition used in iteration will be until there is a line present in the file. Read it and print; otherwise, terminate the loop using the scanner.Scan() function.

  • Step 7 If an error occurs while scanning, print the error on the console using fmt.Println().

Example

In this example, we will use a scanner to read the contents of a file line by line.

package main
import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    myfile, err := os.Open("file1.txt")  //open the file
    if err != nil {
        fmt.Println("Error opening file:", err)
        return
    }
    defer myfile.Close()

    scanner := bufio.NewScanner(myfile)  //scan the contents of a file and print line by line
    for scanner.Scan() {
        line := scanner.Text()
        fmt.Println(line)
    }

    if err := scanner.Err(); err != nil {
        fmt.Println("Error reading from file:", err) //print error if scanning is not done properly
    }
}

Output

If the file exists, the output will be −

line 1
line 2
line 3

If the file doesn't exists, the output will be −

Error reading file: open file1.txt: no such file or directory

Method 2: Using io/ioutil and strings package

This instance uses ioutil.ReadFile to read the contents of the file into memory as []bytes using the function. The string function and the strings package are then used to turn the contents into a string. The string is divided into a number of lines, each separated by a newline character, using the Split function. The for loop then prints each line after iterating through the lines.

Syntax

ioutil.ReadFile

This function is available in the ioutil package and is used to read the contents of a file with the filename as input.

Algorithm

  • Step 1 Create a package main and declare fmt (format package), io/ioutil, and strings package in the program where main produces executable codes and fmt helps in formatting input and output.

  • Step 2 Create a main function and read the file file1.txt using ioutil.ReadFile function.

  • Step 3 If an error occurs while reading the file, print the error and return.

  • Step 4 Use strings.Split function to split the data using \n.

  • Step 5 Iterate through the split string and print the content line by line.

  • Step 6 The print statement is executed using fmt.Println() function where \n means new line.

Example

In this example, we will use ioutil.ReadFile function from the io package.

package main
import (
   "fmt"
   "io/ioutil"
   "strings"
)

func main() {
   data, err := ioutil.ReadFile("file1.txt")  //read the file 
   if err != nil {
      fmt.Println("Error reading file:", err) //print the error if occurs while reading file 
      return
   }
   read_lines := strings.Split(string(data), "\n")
   for _, line := range read_lines {
      fmt.Println(line) //print the content line by line
   }
}

Output

If the file exists, the output will be −

line 1
line 2
line 3

If the file doesn't exists, the output will be −

Error reading file: open file1.txt: no such file or directory

Key points for Reading Files in Golang

Following is the keypoints for reading files line by line −

  • Performance points: When choosing a method, consider the file size and the available memory. The ioutil.ReadFile method loads the entire file into memory, which may not be suitable for very large files.
  • Error Handling: Robust error handling ensures that the program behaves correctly if an error occurs while reading the file.
  • Buffer Size: The bufio.Scanner has a default buffer size. If you need to read very large lines, you can adjust the buffer size using the scanner.Buffer() method.
  • Reading Large Files: For very large files, consider reading the file in smaller chunks to avoid running out of memory.
  • Edge Cases: Handle edge cases such as empty lines or files that do not end with a newline character.

We explored how to read the content of a file line by line using two methods in Golang. The first method uses the bufio and os packages, and the second method uses the io/ioutil package. Additionally, we discussed key points such as performance, error handling, buffer size, and edge cases to ensure a robust implementation.

Advertisements