✍️ Write to a file in Go
Table of Contents
Go has excellent built-in support for file operations. Using the os package, you can easily open, read from, write to and close the file. In this example, we focus on writing data to a file. We show you how you can write text and binary data in different ways - entire data at once, line by line, as an array of bytes in a specific place, or in a buffered manner.
Write the entire content to a file at once #
The shortest way of writing data to a file is to use the os.WriteFile() function. It takes three input parameters:
- Path to the file that we want to write to
- Byte data which we want to write to the file
- Permission bits of the file that will be created
Creating and closing the file is done by the function itself, so it’s no need to create or close the file before and after writing.
If you are using the Go version earlier than 1.16, you will find the
WriteFile()function in theioutilpackage.
package main
import (
"log"
"os"
)
func main() {
if err := os.WriteFile("file.txt", []byte("Hello GOSAMPLES!"), 0666); err != nil {
log.Fatal(err)
}
}
Write text data to a file line by line #
If you have your file’s lines in separate variables, an array, or want to do some processing before writing a single line, you can write the data line by line using the func (*File) WriteString() method. All you need to do is create a file, write your strings to it, and finally close the file.
package main
import (
"log"
"os"
)
var lines = []string{
"Go",
"is",
"the",
"best",
"programming",
"language",
"in",
"the",
"world",
}
func main() {
// create file
f, err := os.Create("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file
defer f.Close()
for _, line := range lines {
_, err := f.WriteString(line + "\n")
if err != nil {
log.Fatal(err)
}
}
}
Write byte data to a file #
As with writing strings line by line, we can also write byte data using the func (*File) Write() method or func (*File) WriteAt() if you want to write data at a given offset.
package main
import (
"log"
"os"
)
var bytes = []byte{
0x47, // G
0x4f, // O
0x20, // <space>
0x20, // <space>
0x20, // <space>
0x50, // P
0x4c, // L
0x45, // E
0x53, // S
}
var additionalBytes = []byte{
0x53, // S
0x41, // A
0x4d, // M
}
func main() {
// create file
f, err := os.Create("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file
defer f.Close()
// write bytes to the file
_, err = f.Write(bytes)
if err != nil {
log.Fatal(err)
}
// write additional bytes to the file, start at index 2
_, err = f.WriteAt(additionalBytes, 2)
if err != nil {
log.Fatal(err)
}
}
Write formatted strings to a file #
In addition to the File methods, we can use fmt.Fprintln() function to write data to a file. This function formats its operands, adds spaces between them, a new line at the end, and writes the output to the writer (first argument). It’s great for simple line formatting or writing the string representation of a struct to a file.
package main
import (
"fmt"
"log"
"os"
)
var lines = []string{
"Go",
"is",
"the",
"best",
"programming",
"language",
"in",
"the",
"world",
}
func main() {
// create file
f, err := os.Create("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file
defer f.Close()
for _, line := range lines {
_, err := fmt.Fprintln(f, "*", line, "*")
if err != nil {
log.Fatal(err)
}
}
}
Write to a file using a buffered writer #
If you frequently write a small amount of data to a file, it can hurt the performance of your program. Each write is a costly system call, and if you don’t need immediate file updates, it is a better idea to group these small writes into one. To do this, we can use bufio.Writer structure. Its writing functions do not save data directly to the file but keep it until the buffer underneath is full (default size is 4096 bytes) or the Flush() method is called. So make sure to call Flush() after the completed write to save the remaining data to the file.
package main
import (
"bufio"
"log"
"os"
)
var lines = []string{
"Go",
"is",
"the",
"best",
"programming",
"language",
"in",
"the",
"world",
}
func main() {
// create file
f, err := os.Create("file.txt")
if err != nil {
log.Fatal(err)
}
// remember to close the file
defer f.Close()
// create new buffer
buffer := bufio.NewWriter(f)
for _, line := range lines {
_, err := buffer.WriteString(line + "\n")
if err != nil {
log.Fatal(err)
}
}
// flush buffered data to the file
if err := buffer.Flush(); err != nil {
log.Fatal(err)
}
}