英文:
How to create nested directories using Mkdir in Golang?
问题
我正在尝试从一个Go可执行文件中创建一组嵌套的目录,例如'dir1/dir2/dir3'。我已经成功地用以下代码创建了一个单独的目录:
os.Mkdir("." + string(filepath.Separator) + c.Args().First(), 0777)
然而,我不知道如何在该目录中创建预定的嵌套目录集合。
英文:
I am trying to create a set of nested directories from a Go executable such as 'dir1/dir2/dir3'. I have succeeded in creating a single directory with this line:
os.Mkdir("." + string(filepath.Separator) + c.Args().First(),0777);
However, I have no idea how to approach creating a predetermined nested set of directories inside of that directory.
答案1
得分: 263
os.Mkdir
用于创建单个目录。如果要创建文件夹路径,请尝试使用以下代码:
os.MkdirAll(folderPath, os.ModePerm)
func MkdirAll(path string, perm FileMode) error
MkdirAll创建一个名为path的目录,以及所有必要的父目录,并返回nil,否则返回一个错误。权限位perm用于MkdirAll创建的所有目录。如果path已经是一个目录,则MkdirAll不执行任何操作并返回nil。
编辑:
已更新为正确使用os.ModePerm
。
要连接文件路径,请使用path/filepath
包,如@Chris的答案所述。
英文:
os.Mkdir
is used to create a single directory. To create a folder path, instead try using:
os.MkdirAll(folderPath, os.ModePerm)
Go documentation
>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.
Edit:
Updated to correctly use os.ModePerm
instead.
For concatenation of file paths, use package path/filepath
as described in @Chris' answer.
答案2
得分: 127
这样你就不需要使用任何魔法数字了:
os.MkdirAll(newPath, os.ModePerm)
另外,你可以使用以下方法来创建路径,而不是使用 + :
import "path/filepath"
path := filepath.Join(someRootPath, someSubPath)
以上代码会自动在每个平台上使用正确的分隔符。
英文:
This way you don't have to use any magic numbers:
os.MkdirAll(newPath, os.ModePerm)
Also, rather than using + to create paths, you can use:
import "path/filepath"
path := filepath.Join(someRootPath, someSubPath)
The above uses the correct separators automatically on each platform for you.
答案3
得分: 9
如果问题是创建所有必要的父目录,你可以考虑使用os.MkDirAll()
函数。
MkdirAll
函数会创建一个名为path的目录,以及所有必要的父目录,并返回nil,或者返回一个错误。
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_")
...
}
(请确保指定一个合理的权限值,如此答案中所提到的)
英文:
If the issue is to create all the necessary parent directories, you could consider using os.MkDirAll()
> MkdirAll
creates a directory named path, along with any necessary parents, and returns nil, or else returns an error.
The path_test.go is a good illustration on how to use it:
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_")
...
}
(Make sure to specify a sensible permission value, as mentioned in this answer)
答案4
得分: 8
可以使用以下类似的实用方法来解决这个问题。
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("创建 a/b/c 时出错", cerr)
}
log.Println("在子目录中创建文件。")
}
这段代码是一个示例,它定义了一个名为ensureDir
的函数,用于确保目录存在。在main
函数中,它首先调用ensureDir
函数来创建目录"a/b/c",然后使用os.Create
函数创建文件"d.txt"。如果创建目录或文件时出现错误,将会记录错误信息。最后,它会打印一条消息表示成功创建了一个子目录中的文件。
英文:
An utility method like the following can be used to solve this.
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.")
}
答案5
得分: 8
这是一种实现相同目的的替代方法,它避免了由于具有两个不同的“检查...并...创建”操作而引起的竞态条件。
package main
import (
"fmt"
"os"
)
func main() {
if err := ensureDir("/test-dir"); err != nil {
fmt.Println("目录创建失败,错误信息:" + err.Error())
os.Exit(1)
}
// 继续执行
}
func ensureDir(dirName string) error {
err := os.MkdirAll(dirName, os.ModeDir)
if err == nil || os.IsExist(err) {
return nil
} else {
return err
}
}
英文:
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.MkdirAll(dirName, os.ModeDir)
if err == nil || os.IsExist(err) {
return nil
} else {
return err
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论