How to create nested directory in Golang? [SOLVED]


GO, GOLANG Solutions

In this tutorial we will explore different methods which are possible to create nested directories in golang.

 

Example-1: Create nested directories using os.Mkdir

Here is a simple example where we are creating nested directories inside one parent directory:

package main

import (
	"fmt"
	"os"
)

func main() {

	myDir := "/tmp/topDir"
	// Create the top-level directory
	err := os.Mkdir(myDir, 0755)
	if err != nil {
		panic(err)
	}

	// Create the subdirectories
	err = os.Mkdir(myDir+"/subdir1", 0755)
	if err != nil {
		panic(err)
	}

	err = os.Mkdir(myDir+"/subdir2", 0755)
	if err != nil {
		panic(err)
	}

	fmt.Println("Nested directories created successfully!")
}

Output:

# go run main.go 
Nested directories created successfully!

Verify the directories are created:

# tree /tmp/topDir/
/tmp/topDir/
├── subdir1
└── subdir2

2 directories, 0 files

But this solution is not very Robust, as if the same code is ran again:

# go run main.go 
mkdir /tmp/topDir: file exists

So this code will not check for sub paths, if the parent directory itself is present. The second problem with this code is that it is very big and does not handle multi level of nested directories. In such case we have to use os.Mkdir() multiple times. But let's not get carried away, this also is definitely an option but we can also achieve this using standard libraries. Let's check other examples.

 

Example-2: Check if directory exists and then create nested directories

We will enhance our previous code to first check for existing directory with the same name before trying to create it, to avoid any failures. We will use os.Stat to check if directory exists and use os.Mkdir(myDir, 0755) to create the directories. Similarly we check if the subdirectories exist in the same way, and if they don't exist, we create them using os.Mkdir(subdir1, 0755) and os.Mkdir(subdir2, 0755).

package main

import (
	"fmt"
	"os"
)

func main() {
	myDir := "/tmp/topDir"
	_, err := os.Stat(myDir)
	if os.IsNotExist(err) {
		fmt.Println("creating ", myDir)
		err := os.Mkdir(myDir, 0755)
		if err != nil {
			panic(err)
		}
	}

	subdir1 := myDir + "/subdir1"
	_, err = os.Stat(subdir1)
	if os.IsNotExist(err) {
		fmt.Println("creating ", subdir1)
		err := os.Mkdir(subdir1, 0755)
		if err != nil {
			panic(err)
		}
	}

	subdir2 := subdir1 + "/subdir2"
	_, err = os.Stat(subdir2)
	if os.IsNotExist(err) {
		fmt.Println("creating ", subdir2)
		err := os.Mkdir(subdir2, 0755)
		if err != nil {
			panic(err)
		}
	}
	fmt.Println("Nested directories created successfully!")
}

 

Example-3: Create nested directories using os.MdirAll()

Instead of running os.Mkdir() for every directory and sub-directory, we can use os.MkdirAll() function to create nested directories in single line:

func main() {
    // Create the top-level directory
    err := os.MkdirAll("/path/to/topdir/subdir1/subdir2", 0755)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Nested directories created successfully!")
}

Here is a sample code which will take a string argument representing the complete nested directory structure and creates the directories if they don't exist.

package main

import (
	"fmt"
	"os"
	"path/filepath"
)

func createNestedDirs(path string) error {
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		// Create parent directories if they don't exist
		err = os.MkdirAll(filepath.Dir(path), 0755)
		if err != nil {
			return fmt.Errorf("error creating parent directories: %v", err)
		}
		// Create the directory
		err = os.Mkdir(path, 0755)
		if err != nil {
			return fmt.Errorf("error creating directory: %v", err)
		}
		fmt.Println("Directory created successfully at :", path)
	} else {
		fmt.Println("Directory already exists at :", path)
	}
	return nil
}

func main() {
	path := "/tmp/topdir/subdir1/subdir2"
	err := createNestedDirs(path)
	if err != nil {
		panic(err)
	}
}

In the above example, we created a function createNestedDirs(path string) error which takes a string argument representing the complete nested directory structure. Inside the function we first check if the directory exists by calling os.Stat(path). If the directory doesn't exist, we create it using os.MkdirAll(filepath.Dir(path), 0755) which creates all the parent directories, and os.Mkdir(path, 0755) creates the directory.

The filepath.Dir(path) function takes the input path and returns the parent directory of that path, so that all the parent directories are created before creating the final directory.

In the main function, we call createNestedDirs(path) function with the desired directory path, and check for errors.

Output:

$ go run main.go 
Directory created successfully at : /tmp/topdir/subdir1/subdir2

Tree structure of our directories:

# tree /tmp/topdir/
/tmp/topdir/
└── subdir1
    └── subdir2

2 directories, 0 files

 

Example-4: Using shell command (mkdir -p) to create nested directories

In golang you can use exec package to execute shell commands in golang. While most of us already know, in shell it is a one line command to create nested directories so we can also utilise the same in golang with exec.Command() function.

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    path := "/path/to/topdir/subdir1/subdir2"
    cmd := exec.Command("mkdir", "-p", path)
    err := cmd.Run()
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Nested directories created successfully!")
}

In this example, we use the exec.Command function to create a new command to run the mkdir command with the -p option, which creates the parent directories as well if they don't exist. The path variable is passed as the argument to the command which is the path of the nested directory.

The cmd.Run() function runs the command and waits for it to complete, and it returns an error if the command fails.

You can also use cmd.Output() which runs the command and returns the output and error or cmd.Start() which starts the command and returns an error if the command can't be started.

Output

# go run main.go 
Nested directories created successfully!

# tree /path/
/path/
└── to
    └── topdir
        └── subdir1
            └── subdir2

4 directories, 0 files

 

Summary

In this tutorial we covered different methods to create nested directories in golang. The most used function is os.Mkdir() which can create nested directories for you or alternatively we can add additional enhancement to the code to first check for existing directories and create only if it doesn't exist by using os.IsNotExist() function. We can also use shell command mkdir -p </path/to/dir> using exec.Command() function to achieve this.

 

References

How to create nested directories using Mkdir in Golang?

 

Deepak Prasad

Deepak Prasad

He is the founder of GoLinuxCloud and brings over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels in various domains, from development to DevOps, Networking, and Security, ensuring robust and efficient solutions for diverse projects. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment