【问题标题】:How to create nested directories using Mkdir in Golang?如何在 Golang 中使用 Mkdir 创建嵌套目录?
【发布时间】:2015-04-11 11:32:57
【问题描述】:

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

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

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

【问题讨论】:

    标签: go mkdir


    【解决方案1】:

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

    os.MkdirAll(folderPath, os.ModePerm)
    

    Go documentation

    func MkdirAll(path string, perm FileMode) 错误

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

    编辑:

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

    【讨论】:

    • 您可能需要在0755os.ModePerm 之间进行选择。
    【解决方案2】:

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

    os.MkdirAll(newPath, os.ModePerm)
    

    另外,您可以使用以下命令,而不是使用 + 创建路径:

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

    上面自动为您在每个平台上使用正确的分隔符。

    【讨论】:

      【解决方案3】:

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

      (确保指定一个合理的权限值,如this answer 中所述)

      【讨论】:

        【解决方案4】:

        可以使用如下的实用方法来解决这个问题。

        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】:

          这是实现相同目标的一种替代方法,但它避免了由两个不同的“检查..和..创建”操作引起的竞争条件。

          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
              }
          }
          

          【讨论】:

          • MkdirAll: "如果 path 已经是目录,MkdirAll 什么都不做,返回 nil。",所以不需要检查IsExist 错误
          猜你喜欢
          • 2014-12-27
          • 1970-01-01
          • 2022-01-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-06
          相关资源
          最近更新 更多