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?