mkdir if not exists using golang
GoDirectoryPathFilepathMkdirGo Problem Overview
I am learning golang(beginner) and I have been searching on both google and stackoverflow but I could not find an answer so excuse me if already asked, but how can I mkdir if not exists in golang.
For example in node I would use fs-extra with the function [ensureDirSync] 1 (if blocking is of no concern of course)
fs.ensureDir("./public");
Go Solutions
Solution 1 - Go
Okay I figured it out thanks to this question/answer
import(
"os"
"path/filepath"
)
newpath := filepath.Join(".", "public")
err := os.MkdirAll(newpath, os.ModePerm)
// TODO: handle error
Relevant Go doc for MkdirAll:
> MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. > > ... > > If path is already a directory, MkdirAll does nothing and returns nil.
Solution 2 - Go
I've ran across two ways:
-
Check for the directory's existence and create it if it doesn't exist:
if _, err := os.Stat(path); os.IsNotExist(err) { err := os.Mkdir(path, mode) // TODO: handle error }
However, this is susceptible to a race condition: the path may be created by someone else between the os.Stat
call and the os.Mkdir
call.
-
Attempt to create the directory and ignore any issues (ignoring the error is not recommended):
_ = os.Mkdir(path, mode)
Solution 3 - Go
You can use os.Stat
to check if a given path exists.
If it doesn't, you can use os.Mkdir
to create it.
Solution 4 - Go
This is one alternative for achieving the same but it avoids race condition caused by having two distinct "check ..and.. create" operations.
package main
import (
"fmt"
"os"
)
func main() {
if err := ensureDir("/test-dir"); err != nil {
fmt.Println("Directory creation failed with error: " + err.Error())
os.Exit(1)
}
// Proceed forward
}
func ensureDir(dirName string) error {
err := os.Mkdir(dirName, os.ModeDir)
if err == nil {
return nil
}
if os.IsExist(err) {
// check that the existing path is a directory
info, err := os.Stat(dirName)
if err != nil {
return err
}
if !info.IsDir() {
return errors.New("path exists but is not a directory")
}
return nil
}
return err
}
Solution 5 - Go
So what I have found to work for me is:
//Get the base file dir
path, err := os.Getwd()
if err != nil {
log.Println("error msg", err)
}
//Create output path
outPath:= filepath.Join(path, "output")
//Create dir output using above code
if _, err := os.Stat(outPath); os.IsNotExist(err) {
os.Mkdir(outPath, 0755)
}
I like the portability of this.
Solution 6 - Go
Or you could attempt creating the file and check that the error returned isn't a "file exists" error
if err := os.Mkdir(path, mode); err != nil && !os.IsExist(err) {
log.Fatal(err)
}