mkdir if not exists using golang

GoDirectoryPathFilepathMkdir

Go 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:

  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)
    

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)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlfredView Question on Stackoverflow
Solution 1 - GoAlfredView Answer on Stackoverflow
Solution 2 - GoAustin HansonView Answer on Stackoverflow
Solution 3 - GoMr. LlamaView Answer on Stackoverflow
Solution 4 - Gopr-palView Answer on Stackoverflow
Solution 5 - Gojust_mylesView Answer on Stackoverflow
Solution 6 - Gohyper_debuggerView Answer on Stackoverflow