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


95

我正在尝试从Go可执行文件(例如'dir1 / dir2 / dir3')创建一组嵌套目录。我已经成功创建了以下目录:

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

但是,我不知道如何在该目录内创建预定的嵌套目录集。

Answers:


176

os.Mkdir用于创建单个目录。要创建文件夹路径,请尝试使用:

os.MkdirAll(folderPath, os.ModePerm)

转到文档

func MkdirAll(路径字符串,烫发FileMode)错误

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

编辑:

更新为正确使用os.ModePerm
要串联文件路径,请使用path/filepath@Chris答案中所述的包。


@CodeWarrior:感谢您的ping。我更新了答案,并对克里斯
阿尼斯(

谢谢@克里斯!:)
Thales P

1
您可能需要在0755和之间进行选择os.ModePerm
updogliu

102

这样,您不必使用任何幻数:

os.MkdirAll(newPath, os.ModePerm)

另外,您可以使用:

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

上面的代码会自动在每个平台上使用正确的分隔符。


2
这是正确的答案。更简单,与平台无关。
丹·埃斯帕萨

6

如果问题是创建所有必要的父目录,则可以考虑使用 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_")
...
}

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


3

可以使用如下所示的实用方法来解决此问题。

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.")
}

1

这是达到相同目的的一种选择,但是它避免了由于具有两个不同的“检查和创建”操作而导致的竞争状态。

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
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.