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

Ana*_*Ana 8 directory go

我想func FolderExists(path string) bool这会告诉文件夹是否存在且是否可写.我来到这里:

func FolderExists(path string) bool {
    info, err := os.Stat(path)
    return os.IsExist(err) && info.Mode().IsDir() && info.Mode().???
}
Run Code Online (Sandbox Code Playgroud)

如何判断此文件夹是否可写?我不能简单地检查文件模式权限(例如0200用于用户写入权限),因为那时我必须检查文件的所有者.在Go中有一种直接的方法吗?

对于那些具有UNIX背景的人来说,寻找相当于非常简单的东西:

if [ -d "$n" && -w "$n" ] ; then ... fi
Run Code Online (Sandbox Code Playgroud)

two*_*two 9

如果你正在为Unix-y操作系统编写,你可以使用unix.Access(path string, mode uint32) error常量unix.W_OK作为mode.

正如kostix所说,当您访问目录时(例如,创建或删除文件时),您仍然需要检查错误.自检查以来,该目录可能已被删除,或者权限可能已更改,或者您可能会收到完全无关的错误.

(感谢用户fxxn指出自2013年的原始答案以来情况有所改善,即使用syscall.Access并从中提取W_OK常量unistd.h.)

这是检查存在和访问的代码,它在Linux上获得了预期的结果:

package main

import (
    "fmt"
    "golang.org/x/sys/unix"
)

func writable(path string) bool {
    return unix.Access(path, unix.W_OK) == nil
}

func main() {
    fmt.Println("/etc writable?", writable("/etc"))
    fmt.Println("/tmp writable?", writable("/tmp"))
}
Run Code Online (Sandbox Code Playgroud)


Gau*_*ham 7

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

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

file-perm /
    file-perm.go
    is-writable.go
    is-writable_windows.go
Run Code Online (Sandbox Code Playgroud)

文件:文件-perm.go

package main

import (
    "fmt"
)

func main() {
    path := "/tmp/xyz"

    fmt.Println(IsWritable(path))
}
Run Code Online (Sandbox Code Playgroud)

文件: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
}
Run Code Online (Sandbox Code Playgroud)

文件: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
}
Run Code Online (Sandbox Code Playgroud)

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