Go语言 如何正确示例化os.FileMode

cfh9epnr  于 2022-12-07  发布在  Go
关注(0)|答案(4)|浏览(132)

我看过无数的例子和教程,展示了如何创建一个文件,所有这些都是通过设置文件的权限位来“作弊”的。我想知道/找出如何正确地示例化os.FileMode,以便在创建/更新文件时提供给编写者。
下面是一个粗略的例子:

func FileWrite(path string, r io.Reader, uid, gid int, perms string) (int64, error){
    w, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0664)
    if err != nil {
        if path == "" {
            w = os.Stdout
        } else {
            return 0, err
        }
    }
    defer w.Close()

    size, err := io.Copy(w, r)

    if err != nil {
        return 0, err
    }
    return size, err
}

在上面的基本函数中,设置了权限位0664,虽然这可能有意义,但有时我更喜欢正确设置文件模式的正确方法。如上所述,一个常见的例子是UID / GID是已知的,并已作为int值提供,权限是八进制数字,这些数字已预先收集并作为字符串插入到数据库中。

4uqofj5v

4uqofj5v1#

我的解决方法是定义我自己的常量,因为我在操作系统或系统调用中找不到任何常量:

const (
        OS_READ = 04
        OS_WRITE = 02
        OS_EX = 01
        OS_USER_SHIFT = 6
        OS_GROUP_SHIFT = 3
        OS_OTH_SHIFT = 0

        OS_USER_R = OS_READ<<OS_USER_SHIFT
        OS_USER_W = OS_WRITE<<OS_USER_SHIFT
        OS_USER_X = OS_EX<<OS_USER_SHIFT
        OS_USER_RW = OS_USER_R | OS_USER_W
        OS_USER_RWX = OS_USER_RW | OS_USER_X

        OS_GROUP_R = OS_READ<<OS_GROUP_SHIFT
        OS_GROUP_W = OS_WRITE<<OS_GROUP_SHIFT
        OS_GROUP_X = OS_EX<<OS_GROUP_SHIFT
        OS_GROUP_RW = OS_GROUP_R | OS_GROUP_W
        OS_GROUP_RWX = OS_GROUP_RW | OS_GROUP_X

        OS_OTH_R = OS_READ<<OS_OTH_SHIFT
        OS_OTH_W = OS_WRITE<<OS_OTH_SHIFT
        OS_OTH_X = OS_EX<<OS_OTH_SHIFT
        OS_OTH_RW = OS_OTH_R | OS_OTH_W
        OS_OTH_RWX = OS_OTH_RW | OS_OTH_X

        OS_ALL_R = OS_USER_R | OS_GROUP_R | OS_OTH_R
        OS_ALL_W = OS_USER_W | OS_GROUP_W | OS_OTH_W
        OS_ALL_X = OS_USER_X | OS_GROUP_X | OS_OTH_X
        OS_ALL_RW = OS_ALL_R | OS_ALL_W
        OS_ALL_RWX = OS_ALL_RW | OS_GROUP_X
)

这就允许我直接指定我的意图:

// Create any directories needed to put this file in them
        var dir_file_mode os.FileMode
        dir_file_mode = os.ModeDir | (OS_USER_RWX | OS_ALL_R)
        os.MkdirAll(dir_str, dir_file_mode)

我相信这可以通过使用iota和更多的权限组合来改进,但它现在对我很有效。

0s7z1bwu

0s7z1bwu2#

FileMode只是一个uint32。http://golang.org/pkg/os/#FileMode
通过常量进行设置并不是“作弊”,你可以像使用其他数值一样使用它。如果你没有使用常量,你可以对有效的数值进行转换:

mode := int(0777)
os.FileMode(mode)
omvjsjqw

omvjsjqw3#

添加到Chris Hopkins答案
可以通过执行fs.fileMode(dir_file_mode)将该值转换为fs.fileMode类型
此外,在定义的常量中有一个排印错误:

OS_ALL_RWX = OS_ALL_RW | OS_GROUP_X (Incorrect)

OS_ALL_RWX = OS_ALL_RW | OS_ALL_X (Correct)
2izufjch

2izufjch4#

除了Chris霍普金斯的回答之外,您还可以在syscall包中找到使用POSIX C API中使用的相同命名约定来组合任何文件权限所需的值。
因此,不要通过计算来定义自己的常数(从Chris的回答中可以看出,这仍然是微不足道的)

OS_USER_R = OS_READ<<OS_USER_SHIFT

您可以使用

// user read, write, execute bit
syscall.S_IRUSR
syscall.S_IWUSR
syscall.S_IXUSR
// group read, write, execute bit
syscall.S_IRGRP
syscall.S_IWGRP
syscall.S_IXGRP
// world/other read, write, execute bit
syscall.S_IROTH
syscall.S_IWOTH
syscall.S_IXOTH

然后,您可以根据需要编写任何其他代码,或者使用一些与POSIX C API匹配的其他预定义代码,或者使用S_IREAD, S_IWRITE, S_IEXEC等简写。

相关问题