How to create a directory if it does not exist in Go
Creating a directory in Go can be done through the os.Mkdir
method in the standard library. However, if you try to create a directory that already exists, you will get a PathError
notifying you of the problem. This short article will help you solve the problem of selectively creating a directory if it does not exist in Go
path := "sample"
// ignore the error
_ = os.Mkdir(path, os.ModePerm)
Ignoring the error from os.Mkdir()
(as shown above) can be an acceptable
solution since the error just reports that the directory already exists.
However, ignoring errors is generally frowned upon so it’s better to handle this
possibility in a proper manner. There are two main ways to solve this problem
depending on what you’re trying to achieve.
1. Check for the directory’s existence first
The first method involves checking to see if the directory exists first before attempting to create it. This is a straightforward process in Go:
package main
import (
"errors"
"log"
"os"
)
func main() {
path := "sample"
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
err := os.Mkdir(path, os.ModePerm)
if err != nil {
log.Println(err)
}
}
}
The os.Stat()
method is used to get information about a given path. The error
from os.Stat()
is compared with os.ErrNotExist
using the Is()
method from
the errors
package to see if it reports that the directory represented by
path
does not exist. You might see older code use the os.IsNotExist()
method
for this comparison but this is the modern way for Go 1.13 and later. If the
error from os.Stat()
is nil
(which means the path exists), the comparison
will fail and the contents of the outermost if
block will not be executed.
2. Recursively create all directories
A second way to solve this problem involves the use of the os.MkdirAll()
method which is handy if you want to create several directories recursively
including any missing parents. Unlike os.Mkdir
, it does not return an error of
any if the directories in the path already exists. This means you can safely use
this method without having checks for whether a directory in the path exists or
not.
package main
import (
"log"
"os"
)
func main() {
path := "sample/deeply/nested/directory"
err := os.MkdirAll(path, os.ModePerm)
if err != nil {
log.Println(err)
}
}
When using os.MkdirAll()
you may encounter an error if the path exists but is
not a directory. Otherwise, you won’t encounter any errors as already existing
directory paths are left alone without any modifications.
Thanks for reading, and happy coding!