5 easy ways to read a file in Golang [Practical Examples]

In this article we are discussing different ways to read files in Golang. We read the text and binary files. To read files in Go, we use the os, ioutil, io, and bufio packages.

There are many ways to read a file. Here we will explore some of the common and effective ways to read a file in Go.

Advertisement
  • Read the entire file
  • Read file on a specific chunk
  • Read file line by line
  • Read file word by word

 

How to Open a file for reading in GoLang

We are using the os package Open() function to open the file for reading. This is the initial step in reading a file's content. Error is recorded using the error package.

file, err := os.Open("filename.extension")

After the reading operation is done, it's essential to ensure that the file is closed. Thus defer keyword is used to send the function execution at last.

defer file.close() // closes the file after reading operation is done.

Our reading operations happen between file opening and closing operations.

Follow is text.txt content which we will use through out this article:

Advertisement
Welcome to the GoLinuxCloud program.
We have robust systems and study programs underway.
Join us and study various languages starting with GoLang.

 

1. Read the entire file in GoLang

In Go, Reading an entire file content/text is to use ReadFile() function from the ioutil/os package. This function reads the entire content of the file into a byte slice. The ioutil package should not be used in reading a large file thus the function is quite sufficient for small files. Below is the implementation of how to use it.

package main

import (
   "fmt"
   "io/ioutil"
   "os"
)

func main() {
   // get file from terminal
   inputFile := os.Args[1]
   // read the whole content of file and pass it to file variable, in case of error pass it to err variable
   file, err := ioutil.ReadFile(inputFile)
   if err != nil {
      fmt.Printf("Could not read the file due to this %s error \n", err)
   }
   // convert the file binary into a string using string
   fileContent := string(file)
   // print file content
   fmt.Println(fileContent)
}

Explanation:-

inputFile;- We are getting file inputs from the terminal and using the os package Args[] function to get the file parameter as a string.

file, err := ioutil.ReadFile(inputFile) :- This ioutil package as ReadFile() function capable of reading the whole file content and map the results into file variable. It receives filename from inputFile variable. We have an error check in case the reading of file content wasn’t successful and print the nature of the error.

fileContent: = string(file):- Finally we need to convert the file content into a string using the string function. Print the whole fileContent into the user's terminal using the fmt package Println() function.

Output:-

 $ go run main.go text.txt
Welcome to the GoLinuxCloud program.
We have robust systems and study programs underway.
Join us and study various languages starting with GoLang.

 

2. Read file in chunks in GoLang

In Go, Reading a file in chunks is the most efficient approach. Thus it doesn’t take the whole file content completely into the memory but is loaded in a specific chunk. It is essential because reading a whole file at once may lead to memory leakage or memory errors.

Below is the implementation of the reading file in a chunk in GoLang

package main

import (
   "fmt"
   "io"
   "os"
   "strconv"
)

func main() {
   // get file from terminal
   inputFile := os.Args[1]
   // declare chunk size
   maxSz, _ := strconv.Atoi(os.Args[2])
   // read the whole content of file and pass it to file variable, in case of error pass it to err variable
   file, err := os.Open(inputFile)
   if err != nil {
      fmt.Printf("Could not open the file due to this %s error \n", err)
   }
   defer file.Close()

   // create buffer
   b := make([]byte, maxSz)

   for {
      // read content to buffer
      readTotal, err := file.Read(b)
      if err != nil {
         if err != io.EOF {
            fmt.Println(err)
         }
         break
      }
      fileContent := string(b[:readTotal])
      // print content from buffer
      fmt.Println(fileContent)
   }
}

This produces output as shown below when we use a long string

Output:-

$ go run main.go text.txt 10
Welcome to
 the GoLin
uxCloud pr
ogram.
We 
have robus
t systems 
and study 
programs u
nderway.
J
oin us and
 study var
ious langu
ages start
ing with G
oLang.

Explanation:-

The os package Args[] function is used to provide the inputFile and maxSz values respectively for the program. However maxSz values need to be converted into an integer thus we are using strconv package Atoi() function to convert string input value to integer before being stored into maxSz variable.

The os package open() function is used to open file for easy access and read of the content, thus allowing us to use defer keyword to close the file to avoid memory leakage.

b := make([]byte, maxSz) creating a buffer to hold bytes slice of specified length and of defined capacity into which the bytes of the file will be read.

Using the Read() method of the Filetype, it reads up to the specified length and returns the number of bytes read. We store the bytes retuned in a variable. Then the slice is read from index 0 to n-1, up to the number of bytes returned by the Read() method, and printed. The reading loop finishes when an io.EOF error occurs, indicating the end of the file.

Finally, we can print the file content to the terminal using the fmt package Println() function.

 

3. Read file line by line in GoLang

In Go, we can use the bufio package and os package for reading a file content line by line. The process to read a text file line by line include the following steps:

  • Use os.args[] function to read filePath
  • Use os.open() function to open the file.
  • Use bufio.NewScanner() function to create the file scanner.
  • Use bufio.ScanLines() function with the scanner to split the file into lines.
  • Then use the scanner Scan() function in a for loop to get each line and process it.

Here is an example of reading a file line by line in GoLang.

package main

import (
   "bufio"
   "fmt"
   "os"
)

func main() {
   // get file from terminal
   filePath := os.Args[1]
   // read the whole content of file and pass it to file variable, in case of error pass it to err variable
   file, err := os.Open(filePath)
   if err != nil {
      fmt.Printf("Could not open the file due to this %s error \n", err)
   }
   fileScanner := bufio.NewScanner(file)
   fileScanner.Split(bufio.ScanLines)
   
   for fileScanner.Scan(){
      fmt.Println(fileScanner.Text())
   }
   if err = file.Close(); err != nil {
      fmt.Printf("Could not close the file due to this %s error \n", err) 
   }
}

Output:-

$ go run main.go text.txt   
Welcome to the GoLinuxCloud program.
We have robust systems and study programs underway.
Join us and study various languages starting with GoLang.

Explanation:-
Using os.Args[] function accessed filePath, Then we opened a text.txt file. Then we create a new scanner using the file. The scan() method reads the next line of the file, available through the text() method. After Scan returns false, the Err() method will return any error that occurred during scanning. If the error is End of File, Err() will return nil.

NB// We are processing the file lines, which is keeping our resources open for a longer time. We can read the file data into a string array and then process it accordingly. This is not recommended for a very large file though.

 

4. Reading File line by line to String Array in GoLang

It is similar to reading file line by line however, we have to store file content into a slice of an array string. Using var fileLines []string, we can append the text from the file into the fileLines variable and then access line by line later.

Below is an example

package main

import (
   "bufio"
   "fmt"
   "os"
)

func main() {
   // get file from terminal
   filePath := os.Args[1]
   // read the whole content of file and pass it to file variable, in case of error pass it to err variable
   file, err := os.Open(filePath)
   if err != nil {
      fmt.Printf("Could not open the file due to this %s error \n", err)
   }
   fileScanner := bufio.NewScanner(file)
   fileScanner.Split(bufio.ScanLines)
   var fileLines []string

   for fileScanner.Scan() {
      fileLines = append(fileLines, fileScanner.Text())
   }
   if err = file.Close(); err != nil {
      fmt.Printf("Could not close the file due to this %s error \n", err)
   }

   for key, value := range fileLines {
      fmt.Printf("line %v : %s \n", key, value)
   }
}

Output:-

$ go run main.go text.txt 
line 0 : Welcome to the GoLinuxCloud program. 
line 1 : We have robust systems and study programs underway. 
line 2 : Join us and study various languages starting with GoLang.

Explanation:-

Using os.Args[] function accessed filePath, Then we opened a text.txt file.Then we create a new scanner using the file. The scan() method reads the next line of the file, available through the text() method. Scans results are appended to an array of strings. After Scan returns false, the Err() method will return any error that occurred during scanning. If the error is End of File, Err() will return nil.

 

5. Read file word by word in GoLang

The implementation is similar to read file line by line in Go, we just add the ScanWords from bufio package can be used to read a file word by word.

Below is an example

package main

import (
   "bufio"
   "fmt"
   "os"
)

func main() {
   // get file from terminal
   filePath := os.Args[1]
   // read the whole content of file and pass it to file variable, in case of error pass it to err variable
   file, err := os.Open(filePath)
   if err != nil {
      fmt.Printf("Could not open the file due to this %s error \n", err)
   }
   defer file.Close()

   fileScanner := bufio.NewScanner(file)
   fileScanner.Split(bufio.ScanWords)

   var fileLines []string

   for fileScanner.Scan() {
      fileLines = append(fileLines, fileScanner.Text())
   }
   if err := fileScanner.Err(); err != nil {
      fmt.Printf("Could not scan the file due to this %s error \n", err)
   }

   for key, value := range fileLines {
      fmt.Printf("word_No: %v -> %s \n", key, value)
   }
}

Output:-

$ go run main.go text.txt 

word_No: 0 -> Welcome 
word_No: 1 -> to 
word_No: 2 -> the 
word_No: 3 -> GoLinuxCloud 
word_No: 4 -> program. 
word_No: 5 -> We 
word_No: 6 -> have 
word_No: 7 -> robust 
word_No: 8 -> systems 
word_No: 9 -> and 
word_No: 10 -> study 
word_No: 11 -> programs 
word_No: 12 -> underway. 
word_No: 13 -> Join 
word_No: 14 -> us 
word_No: 15 -> and 
word_No: 16 -> study 
word_No: 17 -> various 
word_No: 18 -> languages 
word_No: 19 -> starting 
word_No: 20 -> with 
word_No: 21 -> GoLang.

Explanation:-

Using os.Args[] function accessed filePath, Then we opened a text.txt file. Then we create a new scanner using the file. The scan() method reads the next word of the file, available through the text() method. Scans results are appended to an array of strings. After Scan returns false, the Err() method will return any error that occurred during scanning. If the error is End of File, Err() will return nil.

 

Summary

It’s very easy to read a file in Go programming. We can read the file contents line by line, chunk, word by word, file content to string, process them or we can store into a string array and process them later on. We should always close the file resources as soon as our work is done.

 

References

Readfile in Go
How to read file in Golang

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X