如何在 Golang 中使用 Mkdir 创建嵌套目录?
How to create nested directories using Mkdir in Golang?
我正在尝试从 Go 可执行文件创建一组嵌套目录,例如 'dir1/dir2/dir3'。我已经成功地用这一行创建了一个目录:
os.Mkdir("." + string(filepath.Separator) + c.Args().First(),0777);
但是,我不知道如何在该目录中创建一组预定的嵌套目录。
os.Mkdir
用于创建单个目录。要创建文件夹路径,请尝试使用:
os.MkdirAll(folderPath, os.ModePerm)
func MkdirAll(path string, perm FileMode) error
MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. The permission bits perm are used for all directories that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil.
编辑:
已更新以正确使用 os.ModePerm
。
对于文件路径的串联,请使用包 path/filepath
,如@Chris 的回答中所述。
如果问题是创建所有必要的父目录,您可以考虑使用 os.MkDirAll()
MkdirAll
creates a directory named path, along with any necessary parents, and returns nil, or else returns an error.
path_test.go 很好地说明了如何使用它:
func TestMkdirAll(t *testing.T) {
tmpDir := TempDir()
path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
err := MkdirAll(path, 0777)
if err != nil {
t.Fatalf("MkdirAll %q: %s", path, err)
}
defer RemoveAll(tmpDir + "/_TestMkdirAll_")
...
}
(确保指定合理的权限值,如 this answer 中所述)
这样您就不必使用任何幻数:
os.MkdirAll(newPath, os.ModePerm)
此外,除了使用 + 创建路径,您还可以使用:
import "path/filepath"
path := filepath.Join(someRootPath, someSubPath)
以上内容会自动在每个平台上为您使用正确的分隔符。
可以使用如下实用方法来解决这个问题。
import (
"os"
"path/filepath"
"log"
)
func ensureDir(fileName string) {
dirName := filepath.Dir(fileName)
if _, serr := os.Stat(dirName); serr != nil {
merr := os.MkdirAll(dirName, os.ModePerm)
if merr != nil {
panic(merr)
}
}
}
func main() {
_, cerr := os.Create("a/b/c/d.txt")
if cerr != nil {
log.Fatal("error creating a/b/c", cerr)
}
log.Println("created file in a sub-directory.")
}
这是实现相同目的的一种替代方法,但它避免了由于具有两个不同的 "check ..and.. create" 操作而导致的竞争条件。
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.MkdirAll(dirName, os.ModeDir)
if err == nil || os.IsExist(err) {
return nil
} else {
return err
}
}
我正在尝试从 Go 可执行文件创建一组嵌套目录,例如 'dir1/dir2/dir3'。我已经成功地用这一行创建了一个目录:
os.Mkdir("." + string(filepath.Separator) + c.Args().First(),0777);
但是,我不知道如何在该目录中创建一组预定的嵌套目录。
os.Mkdir
用于创建单个目录。要创建文件夹路径,请尝试使用:
os.MkdirAll(folderPath, os.ModePerm)
func MkdirAll(path string, perm FileMode) error
MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. The permission bits perm are used for all directories that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil.
编辑:
已更新以正确使用 os.ModePerm
。
对于文件路径的串联,请使用包 path/filepath
,如@Chris 的回答中所述。
如果问题是创建所有必要的父目录,您可以考虑使用 os.MkDirAll()
MkdirAll
creates a directory named path, along with any necessary parents, and returns nil, or else returns an error.
path_test.go 很好地说明了如何使用它:
func TestMkdirAll(t *testing.T) {
tmpDir := TempDir()
path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
err := MkdirAll(path, 0777)
if err != nil {
t.Fatalf("MkdirAll %q: %s", path, err)
}
defer RemoveAll(tmpDir + "/_TestMkdirAll_")
...
}
(确保指定合理的权限值,如 this answer 中所述)
这样您就不必使用任何幻数:
os.MkdirAll(newPath, os.ModePerm)
此外,除了使用 + 创建路径,您还可以使用:
import "path/filepath"
path := filepath.Join(someRootPath, someSubPath)
以上内容会自动在每个平台上为您使用正确的分隔符。
可以使用如下实用方法来解决这个问题。
import (
"os"
"path/filepath"
"log"
)
func ensureDir(fileName string) {
dirName := filepath.Dir(fileName)
if _, serr := os.Stat(dirName); serr != nil {
merr := os.MkdirAll(dirName, os.ModePerm)
if merr != nil {
panic(merr)
}
}
}
func main() {
_, cerr := os.Create("a/b/c/d.txt")
if cerr != nil {
log.Fatal("error creating a/b/c", cerr)
}
log.Println("created file in a sub-directory.")
}
这是实现相同目的的一种替代方法,但它避免了由于具有两个不同的 "check ..and.. create" 操作而导致的竞争条件。
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.MkdirAll(dirName, os.ModeDir)
if err == nil || os.IsExist(err) {
return nil
} else {
return err
}
}