【问题标题】:How to properly instantiate os.FileMode如何正确实例化 os.FileMode
【发布时间】:2015-05-12 05:30:28
【问题描述】:

我看过无数示例和教程,它们展示了如何创建文件,所有这些示例和教程都通过设置文件的权限位来“作弊”。我想知道/了解如何正确实例化 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 值提供,而 perms 是以前收集并作为字符串插入到数据库中的八进制数字。

【问题讨论】:

    标签: go int file-permissions


    【解决方案1】:

    我的解决方法是定义我自己的常量,因为我在 os 或 syscall 中找不到任何常量:

        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 和更多权限组合来改进,但它现在对我有用。

    【讨论】:

    • 克里斯这真的很有用,而且这个 2 岁以上的老问题仍在被关注/更新这一事实表明需要在标准库中提供常量。
    【解决方案2】:

    FileMode 只是一个 uint32。 http://golang.org/pkg/os/#FileMode

    通过常量设置不是“作弊”,您可以像使用其他数值一样使用它。如果您不使用常量,则可以对有效数值使用转换:

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

    【讨论】:

    • 谢谢吉姆,总是乐于助人!
    • 除非我弄错了,否则如果您尝试让某些文件可写而有些文件则不能,这将无济于事。可以有或在(例如)0200 中打开用户可写,但如果有一个 os 常量来控制它,它将有助于代码的可读性。是的,我希望每个称职的程序员都知道八进制 unix 权限,但是当可以使用描述性名称时使用魔法值仍然是不好的编程。据我所知,标准库缺少这一点,只是希望每个人都能记住 Unix 文件权限常量。
    • go中0755和755有什么区别?如果没有 0,我的权限将失败。
    • @Ben 0755 是八进制,等于 493 十进制。
    • 我习惯在linux中使用chmod 755 *file*0755 不是一回事吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 2018-02-05
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多