如何使用Golang中的Mkdir创建嵌套目录?

137

我正在尝试从Go可执行文件中创建一组嵌套目录,例如“dir1/dir2/dir3”。我已经成功地使用以下行创建了单个目录:

os.Mkdir("." + string(filepath.Separator) + c.Args().First(),0777);

然而,我不知道如何处理在那个目录中创建预定的嵌套目录集合。

5个回答

265

使用os.Mkdir可以创建单个目录。如果要创建文件夹路径,请尝试使用以下代码:

``` os.MkdirAll(path, perm) ```

请注意,此函数将创建缺失的父级目录。

os.MkdirAll(path, perm)

请注意,此函数将创建缺失的父级目录。

os.MkdirAll(folderPath, os.ModePerm)

Go文档

func MkdirAll(path string, perm FileMode) error

MkdirAll创建名为path的目录(包括任何必要的父级目录),并返回nil,否则返回错误。 MkdirAll创建的所有目录都使用权限位perm。 如果path已经是一个目录,则MkdirAll不执行任何操作并返回nil。

编辑:

更新为正确使用os.ModePerm
对于文件路径的连接,请使用@Chris答案中描述的path/filepath软件包。


5
你可以在 0755os.ModePerm 之间进行选择。 - updogliu

127

用这种方法,您就不必使用任何神奇数字:

os.MkdirAll(newPath, os.ModePerm)

此外,你可以使用以下方式来创建路径,而非使用 + :

import "path/filepath"
path := filepath.Join(someRootPath, someSubPath)

以上代码会为您自动使用正确的分隔符,以适应各个平台。


9
如果问题是创建所有必要的父目录,您可以考虑使用 os.MkDirAll()

MkdirAll 创建一个名为路径的目录以及任何必要的父目录,并返回 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_")
...
}

(请确保指定合理的权限值,如此答案中所述)

9
这是一个实现相同功能的替代方法,但它避免了由于执行两个不同的“检查...并创建”操作而导致的竞争条件。
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
    }
}

3
如果路径已经是目录,MkdirAll 不会执行任何操作,并返回 nil,因此无需检查 IsExist 错误。 - Yihao Gao

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("error creating a/b/c", cerr)
  }
  log.Println("created file in a sub-directory.")
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接