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 theioutil
package.
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)
}
}