Golang read and update same file [SOLVED]


GOLANG Solutions, GO

Author: Tuan Nguyen
Reviewer: Deepak Prasad

In the previous post, we have introduced some examples of working with files in Golang. In today's post, we will walk through how to read and update same file.

 

Different methods to read and update file in GO

Update file using os.OpenFile with os.O_APPEND flag and Write() function

func OpenFile(name string, flag int, perm FileMode) (*File, error): OpenFile is the generalized open call; most users will use Open or Create instead. It opens the named file with specified flag (O_RDONLY etc.). If the file does not exist, and the O_CREATE flag is passed, it is created with mode perm (before umask). If successful, methods on the returned File can be used for I/O. If there is an error, it will be of type *PathError.

Here is an example of reading and appending some text at the end of file:

package main

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

func main() {
	// Append to the file
	file, err := os.OpenFile("test.log", os.O_APPEND, 0660)
	if err != nil {
		log.Fatal(err)
	}

	// print out the content of file before modify
	fmt.Println("Before modified: ")
	scanner := bufio.NewScanner(file) 
	for scanner.Scan() { 
		fmt.Println(scanner.Text()) 
	} 
	if err := scanner.Err(); err != nil { 
		log.Fatal(err) 
	}

	appendContent := `
	This is the append line`
	if _, err := file.Write([]byte(appendContent)); err != nil {
		file.Close() 
		log.Fatal(err)
	}

	if err := file.Close(); err != nil {
		log.Fatal(err)
	}
}

Output:

Before modified: 
This is log file

And the test.log after modified:

This is log file
	This is the append line

 

Using WriteString() function to append string to a file

The example below show how to use WriteString() function to append string to a file:

package main

import (
    "fmt"
    "os"
)

func main() {
    fileData := []byte("This is example of writing line to a file\n")

    // if the WriteFile method failed then returns an error
    err := os.WriteFile("./fileData.txt", fileData, 0666)
    // handle this error
    if err != nil {
        fmt.Println(err)
    }

    content, err := os.ReadFile("./fileData.txt")
    if err != nil {
        fmt.Println(err)
    }

    fmt.Print(string(content[:]))

    file, err := os.OpenFile("./fileData.txt", os.O_APPEND|os.O_WRONLY, 0600)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    if _, err = file.WriteString("new line has been appended\n"); err != nil {
        panic(err)
    }

    content, err = os.ReadFile("./fileData.txt")
    if err != nil {
        fmt.Println(err)
    }

	fmt.Println("After append:")
    fmt.Print(string(content[:]))
}

Output:

This is example of writing line to a file
After append:
This is example of writing line to a file
new line has been appended

 

Using WriteAt() function to update a file in Golang

Using the WriteAt() function, which writes len(b) bytes to the File beginning at byte offset off. The amount of bytes written and any errors are returned.

func (f *File) WriteAt(b []byte, off int64) (n int, err error): WriteAt writes len(b) bytes to the File starting at byte offset off. It returns the number of bytes written and an error, if any. WriteAt returns a non-nil error when n != len(b). If file was opened with the O_APPEND flag, WriteAt returns an error.

The first word of a text file is modified in the example below:

package main

import (
	"log"
	"fmt"
	"os"
)

func Modify() {
	// OpenFile with Read Write Mode
	file, err := os.OpenFile("test.txt", os.O_RDWR, 0644)
	
	if err != nil {
		log.Fatalf("open file failed: %s", err)
	}
	defer file.Close()
	
	lenUpdate, err := file.WriteAt([]byte("These"), 0) // Write at 0 beginning
	if err != nil {
		log.Fatalf("write to file failed: %s", err)
	}
	fmt.Printf("Length update: %d bytes\n", lenUpdate)
	fmt.Printf("File Name: %s\n", file.Name())
}

func ReadFile() {
	data, err := os.ReadFile("test.txt")
	if err != nil {
		log.Panicf("read data from file failed: %s", err)
	}

	fmt.Printf("File Content: %s\n", string(data[:]))	
}

func main() {
	fmt.Println("Read file before modify")
	ReadFile()
	
	fmt.Println("Using WriteAt function")
	Modify()
	
	fmt.Println("Read file after modify")
	ReadFile()
}

Output:

Read file before modify
File Content: Gello GoLinuxCloud member!
Using WriteAt function
Length update: 5 bytes
File Name: test.txt
Read file after modify
File Content: These GoLinuxCloud member!

 

Buffered read write same file in go

The answer is to double-open the file, once for reading and once for overwriting the data. In the below example, we read every line using a loop and replace "Midas" by "GoLinuxCloud"

package main

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

func main() {
    outFile, _ := os.OpenFile("file.txt", os.O_RDWR, 0777)
    defer outFile.Close()

	file, err := os.OpenFile("file.txt", os.O_RDWR, 0777)
	if err != nil {
		log.Fatal(err)
	}

	reader := bufio.NewReaderSize(file, 10*1024)
    for {
        line, err := reader.ReadString('\n')
		line = strings.Replace(line, "Midas", "GoLinuxCloud", -1)
        outFile.WriteString(line)
        if err != nil {
            if err != io.EOF {
                fmt.Println("error:", err)
            }
            break
        }
    }
}

Output:

There once was a king named GoLinuxCloud who did a good deed for a Satyr. And he was then granted a wish by Dionysus, the god of wine.

For his wish, GoLinuxCloud asked that whatever he touched would turn to gold. Despite Dionysus’ efforts to prevent it, GoLinuxCloud pleaded that this was a fantastic wish, and so, it was bestowed.

Excited about his newly-earned powers, GoLinuxCloud started touching all kinds of things, turning each item into pure gold.

But soon, GoLinuxCloud became hungry. As he picked up a piece of food, he found he couldn’t eat it. It had turned to gold in his hand.

Hungry, GoLinuxCloud groaned, “I’ll starve! Perhaps this was not such an excellent wish after all!”

Seeing his dismay, GoLinuxCloud’ beloved daughter threw her arms around him to comfort him, and she, too, turned to gold. “The golden touch is no blessing,” GoLinuxCloud cried

 

Summary

In this tutorial, we have shown some example of reading updating same file in Golang. We have multiple functions such as: Write(), WriteString(), WriteAt(),... to do this task. It’s incredibly important to understand the various different file permissions available to you when you are writing to new files.

 

References

https://pkg.go.dev/os#FileMode
https://pkg.go.dev/bufio#NewReaderSize

 

Tuan Nguyen

Tuan Nguyen

He is proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

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 send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment