Skip to main content

Files

There are multiple packages we can utilize for reading files in a go program. We'll go over the most commonly used ones in this section. These include: os, io, ioutil and bufio. We'll go over some commonly used methods for each of these packages in this section.

IOUtil

Read Whole File

To read a whole file you can use the ReadFile function.

// Takes a filepath as argument
// Returns a byteslice and an error
byteslice, err := ioutil.ReadFile(filepath)

OS

The os package provides and interface with methods to handle files on your operating system in go.

Open Files

To open a file using the os package, use the Open method. This method takes a filepath and returns the opened file and an error.

file, err := os.Open(filepath)

Reading Files

To read a file using the os package, use the ReadFile method. This method takes a filepath and returns the contents of the file in a byteslice and an error.

byteslice, err := os.ReadFile(filepath)

Writing Files

Getting File Information

To get information about a file using the os package, use the Stat method. This method takes a filepath and information of the selected file and an error. This information includes methods: Name() to get the name of the file, Size() to get the size the file in bytes, Mode() to get the mode of the file, IsDir() to find out if it is a directory, ModTime() showing when the file was last modified, and Sys() describing the underlying data source.

fileInfo, err := os.Stat(filepath)

BufIO

Sometimes opening a whole file is not ideal, this is for example when you have a very large log file. All of it is going to be opened in memory. For these cases you can buffer the IO, this can increase the speed of your application by reducing the number of system calls made. Bufio provides ways to read by the file in batches. Commonly used methods in the bufIO package include: Scanner, ReadSlice,ReadBytes and ReadLines.

Scanner

Breaks the data up in tokens. Open the file with the os Open function and pass the reader to the NewScanner function. This will return a pointer to a Scanner.

myScanner =  bufio.NewScanner(myIOReader)

ReadSlice

This function returns a slice of the passed string based on the delimiter you pass it. It will return every slice with the delimiter. To call it initialize a new reader with the specified string and pass the ReadSlice method a delimiter.

... loading sources

ReadBytes

ReadBytes builds on the ReadSlice functionality and is called in a similar fashion. The difference is that ReadSlice is bound to a buffersize, if it does not reach the delimiter within that size it will fail. ReadBytes is able to call ReadSlice multiple times which means that if you go over the buffersize it won't encounter a problem. To demonstrate:

... loading sources

Examples

Read Lines

The following code provides a way to read lines from a file. It uses the os package to open the file and then bufio to create a scanner that reads the file line by line.

package main

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

func main() {

    file, err := os.Open(filepath)
        if err != nil {
            fmt.Println("Error:", err.Error())
            return
        }
        defer os.Close() // Make sure to always close your resources

    scanner := bufio.NewScanner(file)
    for scanner.Scan() { // returns a boolean, so until the end of the file is reached this loop will run
        fmt.Println(scanner.Text())
    }
}

Read Bytes

package main

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

func main() {

    fileHandler, err := os.Open(filename)
        if err != nil {
            fmt.Println("Error:", err.Error())
            return
        }
        defer os.Close() // Make sure to always close your resources


    myBuffer := make([]byte, size) // Make a buffer with size of size
    for { 
        readBytes, err := fileHandler.Read(buf) 
        if err != nil {
            if err != io.EOF {
                fmt.Println("Error:", err.Error())
                return
            }
            break
        }

        fmt.Println(string(myBuffer[:readBytes]))
    }
}