为了账号安全,请及时绑定邮箱和手机立即绑定

如何判断文件夹是否存在且可写?

如何判断文件夹是否存在且可写?

Go
慕神8447489 2021-07-07 14:07:52
我希望func FolderExists(path string) bool这会告诉文件夹是否存在并且可写。我已经到了这里:func FolderExists(path string) bool {     info, err := os.Stat(path)     return os.IsExist(err) && info.Mode().IsDir() && info.Mode().???}如何判断这个文件夹是否可写?我不能简单地检查文件模式权限(例如,用户写权限为 0200),因为那样我就必须检查文件的所有者。在 Go 中有没有一种直接的方法可以做到这一点?对于那些有 UNIX 背景的人来说,寻找相当于非常简单的:if [ -d "$n" && -w "$n" ] ; then ... fi
查看完整描述

3 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

没有独立于平台的方法来实现这一点,因为在 Windows 上无法检查用户是否创建了目录。因此,我们将针对 Windows 和非 Windows 系统以不同的方式实现它,然后使用 Golang 的构建约束根据操作系统有条件地编译文件。


如图所示,在目录 file-perm 下创建 3 个 .go 文件 -


file-perm /

    file-perm.go

    is-writable.go

    is-writable_windows.go

文件:file-perm.go


package main


import (

    "fmt"

)


func main() {

    path := "/tmp/xyz"


    fmt.Println(IsWritable(path))

}

文件:is-writable.go


这构建在除 Windows 之外的所有平台上,因为 syscall.Stat_t 在 Windows 上不可用。请注意,在构建约束之后需要有一个空行// +build !windows


// +build !windows


package main


import (

    "fmt"

    "os"

    "syscall"

)


func IsWritable(path string) (isWritable bool, err error) {

    isWritable = false

    info, err := os.Stat(path)

    if err != nil {

        fmt.Println("Path doesn't exist")

        return

    }


    err = nil

    if !info.IsDir() {

        fmt.Println("Path isn't a directory")

        return

    }


    // Check if the user bit is enabled in file permission

    if info.Mode().Perm() & (1 << (uint(7))) == 0 {

        fmt.Println("Write permission bit is not set on this file for user")

        return

    }


    var stat syscall.Stat_t

    if err = syscall.Stat(path, &stat); err != nil {

        fmt.Println("Unable to get stat")

        return

    }


    err = nil

    if uint32(os.Geteuid()) != stat.Uid {

        isWritable = false

        fmt.Println("User doesn't have permission to write to this directory")

        return

    }


    isWritable = true

    return

}

文件:is-writable_windows.go


由于文件名中的_windows.go后缀,此文件将仅在 Windows 上构建。更多信息请参考https://golang.org/pkg/go/build/


package main


import (

    "fmt"

    "os"

)


func IsWritable(path string) (isWritable bool, err error) {

    isWritable = false

    info, err := os.Stat(path)

    if err != nil {

        fmt.Println("Path doesn't exist")

        return

    }


    err = nil

    if !info.IsDir() {

        fmt.Println("Path isn't a directory")

        return

    }


    // Check if the user bit is enabled in file permission

    if info.Mode().Perm()&(1<<(uint(7))) == 0 {

        fmt.Println("Write permission bit is not set on this file for user")

        return

    }


    isWritable = true

    return

}

现在,您必须在 file-perm 目录中使用go build,然后运行可执行文件。请注意,它不适用于 go run。


查看完整回答
反对 回复 2021-07-12
?
12345678_0001

TA贡献1802条经验 获得超5个赞

我的回答不会直接回答你的问题,但仍然......

简而言之:不要这样做(除非您正在编写嵌入的东西)。说明:文件系统是完全并发的,因此它们本质上是竞争条件的主题。简单来说,一个序列

  1. 检查文件是否存在。

  2. 如果是,请阅读它。

不会在现实世界中工作,因为文件完全能够在 (1) 和 (2) 之间消失,因为其他进程删除了它。

因此,编写上述序列的唯一真正方法是删除(1)并准备处理(2)中的文件打开错误。

回到您的问题,唯一明智的方法是尝试在目标目录中创建一个文件,并准备好处理由于目录不可写而导致的错误。此外,Go 的错误处理方法是专门针对此类(现实世界)情况量身定制的。


查看完整回答
反对 回复 2021-07-12
  • 3 回答
  • 0 关注
  • 323 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信