Go的os.OpenFile标志参数中管道字符的用途是什么?

时间:2016-05-03 16:24:25

标签: go filesystems pipe bitwise-operators flags

在Go的os包中使用OpenFile函数时,管道符的用途究竟是什么?

示例:

os.OpenFile("foo.txt", os.O_RDWR|os.O_APPEND, 0660)

它是否充当逻辑OR?如果是这样,Go会选择第一个" truthy" ??作为那些标志所代表的常量,它们的核心只是用十六进制编写的整数,在编译时如何选择Go应用哪个标志?

毕竟,如果函数调用的次数最多,os.O_APPEND将优先于传入的所有其他标志,如下所示:

os.O_RDWR == syscall.O_RDWR == 0x2 == 2
os.O_APPEND == syscall.O_APPEND == 0x400 == 1024
os.O_CREATE == syscall.O_CREAT == 0x40 == 64

更新1

要跟进下面的评论,如果我使用os.O_APPEND|os.O_CREATE进行按位运算符计算,那么如果文件存在则会出现错误,或者只是根据需要创建/追加?

更新2

我的问题是双重的,一个是理解按位运算符的目的,我现在理解它更多地用作位掩码运算;二,如何使用os.OpenFile()函数作为创建或追加操作。在我的游戏中,我发现以下组合效果最好:

file, _ := os.OpenFile("foo.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0660)
file.WriteString("Hello World\n")
file.Sync()

这是正确的方法还是有更简洁的方法来做到这一点?

2 个答案:

答案 0 :(得分:4)

这是一个按位,而不是逻辑OR。

如果以二进制形式写出数字,并为每个数字指定真值0/1,并将逻辑OR应用于参数之间的每个位i,然后将结果重新组合为二进制扩展的整数 - |运算符的

它通常以通常被描述为" bitmask"的方式使用。 - 当您希望单个int值表示可以打开或关闭的(小)开关集时,可以使用位掩码。每个开关一位。

在这种情况下,您应该看到A | B表示A中所有开关都已打开,以及B中所有开关都在"上。在您的情况下,开关定义文件打开/创建功能的确切行为,如the Go manual所述。 (可能更详细的是我上面链接的Unix手册页。)

在位掩码中,通常定义代表每个开关的常量 - 这是如何确定那些O_ *常量的。每个都是一个int,只有一位设置并代表一个特定的开关。 (但是,要小心,因为有时它们代表开关的组合!)。

另外:

 ^A  // All of the "switches" not currently on in A
 A&^B // All of the "switches" on in A but not on in B
 A^B  // All of the "switches" on in exactly one of A or B

等。

Go手册here中描述了运算符|本身。

答案 1 :(得分:0)

它是一个按位OR运算符。这里使用的目的是允许将多个值作为位掩码传递。因此,您可以组合标志来创建所需的结果,例如,如果文件不存在,则使用OpenFile()函数创建文件,如果文件不存在则附加到文件。

os.Openfile("foo.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0660

从os包中作为参数传递的常量是从syscall包中赋值的。此程序包包含低级操作系统独立值。

  

包syscall包含低级操作系统原语的接口。细节因底层系统而异,默认情况下,godoc将显示当前系统的系统调用文档。如果您希望godoc显示另一个系统的系统调用文档,请将$ GOOS和$ GOARCH设置为所需的系统。例如,如果要在linux / amd64上查看freebsd / arm的文档,请将$ GOOS设置为freebsd,将$ GOARCH设置为arm。 syscall的主要用途是在其他软件包中提供一个更便携的系统接口,例如" os"," time"和" net"。

https://golang.org/pkg/syscall/

正如@BadZen所说,一个按位OR运算符,在这种情况下,' |'字符,在二进制级别操作,将任何0值更改为1还不是1。

  

你应该在这个背景下看到A | B表示" A中所有开关,以及B中所有开关上的所有开关"。

通过上面显示的函数执行此操作,您正在操作函数的行为以创建具有给定名称os.O_CREATE的文件(foo.txt)或打开文件以进行读/写( os.O_RDWR)并且会附加写入的任何值(os.O_APPEND)。或者,您可以传递os.O_TRUNC以便在写入之前截断文件。

按位OR运算符允许您组合不同行为的强大解决方案,以便从您希望的函数中获取结果。