↓ Skip to main content
Go

Files: GoLang

·4 mins

Learning a new syntax and the libraries is always a task, and the only way forward is gradual. In this blog I will try to create a small program to read a text file and will keep updating the program to include more sophistication

I will not talk about packages, code organization. If required please look at my previous blogs which cover them in detail.

Code: File
#

I will give you the complete code and then explain what all I have done

package files

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

func message(m string) {
	log.Printf(" FILES: %s", m)
}

// ReadFile reads the file and dump contents
func ReadFile(fn string) {
	message("ReadFile Invoked")
	fh, err := os.OpenFile(fn, os.O_RDONLY, 0666)

	if err != nil {
		message(" Unable to open file " + fn)
		os.Exit(1)
	}

	defer fh.Close()
	defer message(" Closing the handle")

	fr := bufio.NewReader(fh)
	for {
		li, err := fr.ReadString('\n')
		if err == nil {
			fmt.Printf(" ><: %s", li)
			continue
		} else if err == io.EOF {
			fmt.Println(" --- End of File ---")
			break
		}
		fmt.Println(" Error:", err)
		break

	}

}

Step 1: Define the package
#

I keep the logic separate form the main package as a habit, and continuing the trend; I define a package files here.

package files

imports will be explained later, but lets define a helper function - message.

Step 2: Function message
#

func message(m string) {
	log.Printf(" FILES: %s", m)
}

The primary purpose of this is printing a debug message with a predefined prefix FILES:

Example
#

2021/01/21 18:46:30  FILES: ReadFile Invoked

Step 3: Function ReadFile
#

Let’s write the function that will read the actual file which will be passed as an argument.

Invoking this function is as easy as importing the package and calling files.ReadFile

Arguments: fn - FileName
#

The ReadFile shall take an argument the file-name that needs to be read for contents. The objective of this function is simple - Dump everything on the STDOUT.

package os - Link#

Package os allows a platform independent interface to Operating System functionality and hence the name O.S.

Function - OpenFile
#

The primary function we will be using the OpenFile. It opens the specified name with the specified flags.

fh, err := os.OpenFile(fn, os.O_RDONLY, 0666)

The official documentation defines the signature of the function as

func OpenFile(name string, flag int, perm FileMode) (*File, error)

Returning the FileHandle - fh and in case of error err.

More about the File can be found here.

Check for error which can indicate file open was failure.

if err != nil {
	message(" Unable to open file " + fn)
	os.Exit(1)
}

Example: readme1.txt
#

In case the file doesn’t exists the error message as below can be seen

2021/01/21 22:45:04  FILES:  Unable to open file readme1.txt

A deferred call to close the file. Which shall render the fh useless for io operation.

defer fh.Close()
defer message(" Closing the handle")

ReadContents: BufferedReader
#

After opening the file it is time to read the contents, for this we will use a bufio package.

NewReader
#

Using the filehandle - fh lets create a reader fr.

fr := bufio.NewReader(fh)

Ideally you should check for nil before you proceed to reading the contents. I am using the ReadString from the reader.

func (b *Reader) ReadString(delim byte) (string, error)

It will read till the occurrence of the first newline (delimiter)

li, err := fr.ReadString('\n')

rest of the code is quite simple that processes

  • Checking error for the invocation of ReadString
  • If no error - dump the contents on stdout
  • In case of error check if it is EOF
  • Else, show the nature of error and break out of the for loop.
if err == nil {
	fmt.Printf(" ><: %s", li)
	continue
} else if err == io.EOF {
	fmt.Println(" --- End of File ---")
	break
}
fmt.Println(" Error:", err)
break

– THE END –
#

Author
Samarthya
Engineer, learner, tinkerer. This is my trophy shelf of everyday work and leisure.

Related

GOLang: Reflection

·3 mins
Must Read # https://blog.golang.org/laws-of-reflection https://golang.org/pkg/reflect/ https://golang.org/pkg/reflect/#Kind https://golang.org/pkg/reflect/#Value Package reflect implements run-time reflection, allowing a program to manipulate objects with arbitrary types. Reflection is a way to examine own structure. Let’s try and learn it via examples.

GOLang: Interfaces

·3 mins
Interfaces are an interesting concept to learn in GOLANG. There are a tonne of informative articles and here is my contribution to it. In classical Object Oriented everything is treated in parlance of Object or Class like in Java or C++. In Go there is no class or inheritance.

Taint Nodes

·1 min
Reference # https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#example-use-cases Before we understand the tainting we should know about the Node Affinity. It the by the virtue of Affinity that pods attracts nodes as a preference or as a basic requirement.