Introduction
Go languages allows developers to create, read and append to a file. In the Go standard library, there is the os package that provides the utilities needed to perform actions like creating, reading and appending a file. This tutorial will introduce you to how to create , read and append a file.
The main focus of this article will be ,
- Create a file in Go
- Write to a file in Go
- Read a file in Go
- Append a file in Go
Prerequisites
- Go runtime
- Basic Go knowledge like understanding of errors, variables etc
- Code editor, I highly recommend VS code, but other editors should be fine as well.
Setup workspace
In your workspace of choice in your computer, create a working directory and add a go file to add our code. Follow the below steps
$ mkdir src $ cd src $ touch main.go $ go mod init example/src
Please note that the src
directory can be named to anything you want.We also initialize go modules, to help us keep track of dependencies on our code.
Create a file in Go
Creating a file is a basic feature for any programming language. In Go, creating file operations is very easy to implement. We will use the os
package that is in the standard library to create a file. In Go the os
package
provides two methods that can be used to create a file name;
os.Create()
os.OpenFile()
Using os.Create()
The os.Create()
method is used to create a file in your program. It takes the name
of the file to create as a parameter and returns the created file
as a pointer and an error
if any exists. If the file already exists it will be truncated. If the file does not exist, it will be created with mode 0666
(before umask). If file creation is successful, methods on the returned file can be used for I/O. The file will be associated with a descriptor of mode 0_RDWR
. If an error is returned it will be of type *PathError
.
Example
package main
import (
"log"
"os"
)
func main() {
filename := "log.txt"
file, err := os.Create(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
}
Explanation
In the above example, we are using the os.Create()
method to create a file called log.txt
. os.Create()
takes as an argument the name of the file that should be created. os.Create()
returns an instance of the created file and error object. To run the above code, in your terminal in the same path as the main.go
file, issue this command $ go run main.go
. If the code runs successfully, a log.txt
file will be created in your root folder.
Using os.OpenFile()
The os.OpenFile
method takes three parameters namely name
of the file, the flag
and the permission mode
. It returns the pointer to the file objects and an error
. os.OpenFile
will open the named file i.e log.txt with the specified flag. The flag is an int type and it's basically an instruction to the os.OpenFile() method. Below are the common flags when working with a file.
- O_RDONLY : Open a file for read only operations
- O_WRONLY : Open a file for write only operations
- O_RDWR : Open a file for read-write
- O_APPEND :It appends data to the file when writing
- O_CREATE: It creates a file if none exists.
The mode of permission is the last argument for os.OpenFile() and is a numeric value referring to the mode the os.OpenFile() will execute with.
Example
package main
import (
"log"
"os"
)
func main() {
filename := "log.txt"
file, err := os.OpenFile(filename, os.O_CREATE, 0644)
if err != nil {
log.Fatal(err)
}
defer file.Close()
}
Explanation
The above example demonstrates creating a file using the os.OpenFile()
method. When the code is executed using this command go run main.go
, a log.txt
file will be created on the root folder.
Write to a file in Go
We now know how to create a file. In this section, we will focus on writing some data into a file. Writing to a file in Go can be achieved in different ways. In this section we will focus on three methods.
File.Write()
File.WriteString()
ioutile.WriteFile()
Using File.Write()
When you successfully create a file, the returned file object has a Write() method that writes bytes from a byte slice to the file. It returns the number of bytes written in the file and an error, if there's any.
Example
package main
import (
"fmt"
"log"
"os"
)
func main() {
filename := "log.txt"
file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer file.Close()
b := []byte("Hello world!")
n, err := file.Write(b)
if err != nil {
log.Fatal(err)
}
fmt.Println("Number of bytes written in the file is ", n)
if err != nil {
log.Fatal(err)
}
}
Ouput
$ go run main.go
Number of bytes written in the file is 12
Explanation
In the above example, we open a file using the os.OpenFile()
method that takes as an argument, the name of the file, the flag and permission. This time round we have two flags union-ed/merged together i.e os.O_Create | os.O_WRONLY
for creating a file and writing in it respectively. We then handle the errors that might occur. Please note that in order to use the Write()
method , we should use slice of bytes , we create a slice of byte using b:= []byte(“Hello world!”)
. To write into the file the command n, err := file.Write(b)
writes into the file. Open your created file e.g log.txt file and see its content.
Using File.WriteString()
This method works just like the file.Write()
method but writes the content of string and not bytes.
Example
package main
import (
"fmt"
"log"
"os"
)
func main() {
filename := "log.txt"
file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer file.Close()
_, err = file.WriteString("Go language is awesome!")
if err != nil {
log.Fatal(err)
}
fmt.Println("Done writing into a file")
}
Output
$ go run main.go
Done writing into a file
Explanation
In the above example, we use the file.WriteString()
method to write string in the log.txt file. Please see the log.txt file if for the written strings
Using ioutil.WriteFile()
The ioutil.WriteFile
method comes from the io/ioutil package
, unlike os.Write()
and os.WriteString()
that comes with a file(any type that implements Reader interface).
It takes as an argument, the filename
to write to, data
to write in byte slice and permission
. It returns an error if there's any. If the file does not exist, WriteFile
creates it with permission, otherwise it will truncate a file before writing if it exists, without changing permission.
As of Go version 1.15, this function exists in the os package as os.WriteFile
. The benefit of using ioutil.WriteFile()
is that it opens and closes the file for you.
Example
package main
import (
"fmt"
"io/ioutil"
"log"
)
func main() {
filename := "log.txt"
data := []byte("Writing Go code is fun!")
err := ioutil.WriteFile(filename, data, 0)
if err != nil {
log.Fatal(err)
}
fmt.Println("Done")
}
Output
$ go run main.go Done
Explanation
In the above example, we use the ioutil.WriteFile()
method to write string data into a log.txt file. After successfully executing the above code, string data will be written in the log.txt file.
Read a file in Go
To read contents of a file, one way is to use the ioutil.ReadFile()
method. It takes as an argument, the file name to be read and returns byte slice and error. A successful read operation returns err == nil
. And not nil == EOF
(End Of File) because ioutil.ReadFile()
reads the whole file. It does not treat an EOF
as an error.
As of Go version 1.16, this function is accessible in the os package as os.ReadFile
.
Create a log.txt file in your root folder and add below data.
This is line one This is line two
Example
package main
import (
"fmt"
"io/ioutil"
"log"
)
func main() {
filename := "log.txt"
data, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))
}
Output
$ go run main.go This is line one This is line two
Append a file in Go
In this section, we open a file in append mode, which will add data into an existing file. The os.O_APPEND flag is used to give permission to the file to allow appending data. We have covered this topic in depth in Golang read and update same file
Example
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
)
func main() {
filename := "log.txt"
line1 := "This is line one \n"
line2 := "This is line two \n"
data := []byte(line1)
err := ioutil.WriteFile(filename, data, 0)
if err != nil {
log.Fatal(err)
}
file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0)
if err != nil {
log.Fatal(err)
}
defer file.Close()
file.WriteString(line2)
fmt.Println("Done")
}
Output
$ go run main.go
Done
Explanation
In the above example, we use the ioutil.WriteFile()
to write into the log.txt file. The os.OpenFile()
method is used with the os.O_APPEND
flag to append data into it.
Summary
This article introduces different methods of Creating , writing , reading into a file using Go. We use os and ioutil packages to help us perform, create, write, read and append a file.
References
https://golangbyexample.com/append-file-golang
https://gobyexample.com/writing-files