mkdir if not exists using golang

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  
}

You can use os.Stat to check if a given path exists.
If it doesn't, you can use os.Mkdir to create it.


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.


I've ran across two ways:

  1. 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.

  1. Attempt to create the directory and ignore any issues (ignoring the error is not recommended):

    _ = os.Mkdir(path, mode)