Please purchase the course to watch this video.

Full Course
Working with files in Go involves understanding how to effectively write data while managing file modes and permissions. Unlike reading files, writing data can present challenges, particularly regarding whether to append to an existing file or truncate it. The os.create
function can be convenient but will replace existing content unless specified otherwise. To append data instead, the os.openFile
function is preferred as it provides more control over file behavior, including flags for read and write permissions and the ability to use O_APPEND
to add data without losing existing content. Correctly setting permissions, such as 0644
, governs user access to the file and ensures that proper read/write privileges are enforced. Understanding these aspects not only simplifies code management but also enhances data integrity when building CLI applications.
No links available for this lesson.
Throughout this course, we've done quite a bit of work when it comes to files. However, for the most part, it's mainly been reading data from them rather than writing data to them. At this point, you may feel like writing data to a file is pretty easy, especially considering that the os.File
type conforms to the io.Writer
interface, which is something we've used often throughout this course. However, when it comes to working with files in the operating system through a CLI application, there's actually a lot more we need to consider, specifically when it comes to file modes and permissions, each of which will differ depending on what our intent is.
Basic File Writing
Let's begin by writing some arbitrary data to a file using the os.Create
function:
file, err := os.Create("data")
if err != nil {
log.Fatal("Failed to create file:", err)
}
// Write some data to the file
fmt.Fprintln(file, os.Args[1])
// Close the file when we're done
file.Close()
When we run this code:
go run main.go "hello world"
It creates a file named "data" with "hello world" in it. If we run the program again with different content:
go run main.go "foo bar"
The original content is replaced with "foo bar". This happens because os.Create
truncates existing files.
Understanding os.Create
If we look at the documentation for os.Create
, we can see it:
- Creates or truncates the named file
- If the file doesn't exist, it creates it with mode 0666 (modified by umask)
- If successful, methods on the returned file can be used for I/O
- The associated file descriptor has mode O_RDWR
Appending to Files
If we want to append to a file instead of truncating it, we need to use os.OpenFile
instead of os.Create
. This function gives us more control over the file behavior:
file, err := os.OpenFile("data.txt", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
log.Fatal("Failed to open file:", err)
}
// Write some data to the file
fmt.Fprintln(file, os.Args[1])
// Close the file when we're done
file.Close()
File Flags
When using os.OpenFile
, we need to specify flags to control the behavior:
-
Access Mode Flags (exactly one must be specified):
os.O_RDONLY
- Read onlyos.O_WRONLY
- Write onlyos.O_RDWR
- Read and write
-
Behavior Flags (combined using bitwise OR
|
):os.O_APPEND
- Append data to the file when writingos.O_CREATE
- Create the file if it doesn't existos.O_EXCL
- Used with O_CREATE, file must not existos.O_SYNC
- Open for synchronous I/Oos.O_TRUNC
- Truncate regular writable file when opened
File Permissions
The third parameter to os.OpenFile
is the permission mode (used when creating a file):
0644
This represents:
- First digit (6): Owner permissions (read + write)
- Second digit (4): Group permissions (read only)
- Third digit (4): Others permissions (read only)
Using O_EXCL
for File Locking
The O_EXCL
flag can be used for simple file locking:
file, err := os.OpenFile("data.txt", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
This will:
- Create the file if it doesn't exist
- Return an error if the file already exists
This is useful for ensuring only one instance of an application can run at a time.
Summary
Working with files in Go involves understanding:
- Which function to use:
os.Create
vsos.OpenFile
- Which flags to use to control behavior (append, create, truncate)
- What permissions to set on the file
By properly controlling these aspects, you can ensure your CLI applications handle files correctly and safely.