如果 mkdir 不存在,则使用 golang

Posted

技术标签:

【中文标题】如果 mkdir 不存在,则使用 golang【英文标题】:mkdir if not exists using golang 【发布时间】:2016-10-22 07:13:38 【问题描述】:

我正在学习 golang(初学者),我一直在 google 和 *** 上搜索,但我找不到答案,如果已经问过,请原谅,但是如果 golang 中不存在,我该如何 mkdir。

例如,在节点中,我将 fs-extra 与函数 ensureDirSync 一起使用(当然,如果不考虑阻塞)

fs.ensureDir("./public");

【问题讨论】:

【参考方案1】:

好的,感谢question/answer

import(
    "os"
    "path/filepath"
)

newpath := filepath.Join(".", "public")
err := os.MkdirAll(newpath, os.ModePerm)
// TODO: handle error

MkdirAll 的相关 Go 文档:

MkdirAll 创建一个名为 path 的目录, 连同任何必要的父母,并返回零, 否则返回错误。

...

如果 path 已经是一个目录,MkdirAll 什么都不做 并返回 nil。

【讨论】:

这是最好的答案,并且正在使用标准库。这在与 os.Create 一起使用时特别有用,您可能还需要在其中创建子目录(在文件的完整路径上使用 filepath.Dir("path/to/file") 在我看来是一个不错的方法。 您可能想要检查 MkdirAll 调用上的任何错误响应,例如:` if err := os.MkdirAll("/somepath/", os.ModeDir); err != nil fmt.Println("无法创建隐藏目录。") `【参考方案2】:

我遇到了两种方式:

    检查目录是否存在,如果不存在则创建:

    if _, err := os.Stat(path); os.IsNotExist(err) 
        err := os.Mkdir(path, mode)
        // TODO: handle error
    
    

但是,这很容易受到竞争条件的影响:路径可能由其他人在 os.Stat 调用和 os.Mkdir 调用之间创建。

    尝试创建目录并忽略任何问题(不建议忽略错误):

    _ = os.Mkdir(path, mode)
    

【讨论】:

如果有人想知道变量 mode 是什么,请参阅:golang.org/pkg/os/#FileMode。您可能希望使用 os.ModeDir 作为其值。 对于那些想知道mode的人,如果您希望能够从同一程序写入该目录,可以使用os.Mkdir("dirname", 0700),请参阅this了解更多详细信息。跨度> 为什么我们在执行 os.Mkdir() 时会忽略任何问题? os.ModeDir模式下创建目录存储文件时。新目录没有足够的权限。我发现只有os.ModePerm 为我工作。相当于0777drwxr-xr-x。我认为权限可能会低一些,但0666 没有做到这一点。 如果其他人在您检查是否存在然后创建目录之间创建目录,选项 1 会不会受到竞争条件的影响?【参考方案3】:

您可以使用os.Stat 检查给定路径是否存在。 如果没有,您可以使用os.Mkdir 创建它。

【讨论】:

【参考方案4】:

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

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.Mkdir(dirName, os.ModeDir)
    if err == nil 
        return nil
    
    if os.IsExist(err) 
        // check that the existing path is a directory
        info, err := os.Stat(dirName)
        if err != nil 
            return err
        
        if !info.IsDir() 
            return errors.New("path exists but is not a directory")
        
        return nil
    
    return err  

【讨论】:

虽然您的代码可能会提供问题的答案,但请在其周围添加上下文,以便其他人了解它的作用以及它存在的原因。 这个答案部分不正确。 os.IsExist(err) 签入ensureDir 是不够的:现有路径不一定是目录。所以ensureDir 将返回一个 nil 错误,但最终路径中的项目可能不是目录(例如,它可能是一个 reguar 文件)。 我已经在对此答案的编辑中解决了我之前评论中描述的问题。【参考方案5】:

所以我发现对我有用的是:

//Get the base file dir
path, err := os.Getwd()
if err != nil 
    log.Println("error msg", err)


//Create output path
outPath:= filepath.Join(path, "output")

//Create dir output using above code
if _, err := os.Stat(outPath); os.IsNotExist(err) 
    os.Mkdir(outPath, 0755)

我喜欢它的便携性。

【讨论】:

【参考方案6】:

或者您可以尝试创建文件并检查返回的错误是否不是“文件存在”错误

if err := os.Mkdir(path, mode); err != nil && !os.IsExist(err) 
    log.Fatal(err)

【讨论】:

这个答案部分不正确。特别是!os.IsExist(err) 检查不正确。现有路径不一定是目录。所以最终代码将继续前进(即log.Fatal不会被执行),但path可能不是一个目录(它可能是一个reguar文件,例如)。

以上是关于如果 mkdir 不存在,则使用 golang的主要内容,如果未能解决你的问题,请参考以下文章

Linux 和 Csharp,检查 Linux 中是不是不存在文件/文件夹,如果存在,则通过 Csharp SSH 运行 MKDIR - [关闭]

如果不存在,则通过将 spring Jpa 与 hibernate 一起使用来创建模式

mkdir -p

文件操作

。。。mkdir与mkdirs的区别。。。

linux mkdir命令详解