如何正确实例化os.FileMode
How to properly instantiate os.FileMode
我看过无数示例和教程,这些示例和教程展示了如何创建文件,并且所有这些都 "cheat" 只需设置文件的权限位即可。我想知道/找出如何正确实例化 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 是八进制数字,之前收集并作为字符串插入到数据库中。
FileMode
只是一个 uint32。 http://golang.org/pkg/os/#FileMode
通过常量设置不是 "cheating",您可以像使用其他数值一样使用它。如果您不使用常量,则可以对有效数值使用转换:
mode := int(0777)
os.FileMode(mode)
我的解决方法是定义自己的常量,因为我在 os 或系统调用中找不到任何常量:
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 和更多的权限组合来改进,但它现在对我有用。
我看过无数示例和教程,这些示例和教程展示了如何创建文件,并且所有这些都 "cheat" 只需设置文件的权限位即可。我想知道/找出如何正确实例化 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 是八进制数字,之前收集并作为字符串插入到数据库中。
FileMode
只是一个 uint32。 http://golang.org/pkg/os/#FileMode
通过常量设置不是 "cheating",您可以像使用其他数值一样使用它。如果您不使用常量,则可以对有效数值使用转换:
mode := int(0777)
os.FileMode(mode)
我的解决方法是定义自己的常量,因为我在 os 或系统调用中找不到任何常量:
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 和更多的权限组合来改进,但它现在对我有用。