Golang坏文件描述符

Golang坏文件描述符,go,file-descriptor,Go,File Descriptor,在go例程中尝试附加到日志文件时,我得到了一个错误的文件描述符 write./log.log:错误的文件描述符 该文件存在,并且具有666的权限。一开始我想可能是因为他们每个人都在试图同时打开文件。我实现了一个互斥来尝试避免这种情况,但是遇到了同样的问题,所以我删除了它 logCh := make(chan string, 150) go func() { for { msg, ok := <-logCh if ok { if

在go例程中尝试附加到日志文件时,我得到了一个错误的文件描述符

write./log.log:错误的文件描述符

该文件存在,并且具有666的权限。一开始我想可能是因为他们每个人都在试图同时打开文件。我实现了一个互斥来尝试避免这种情况,但是遇到了同样的问题,所以我删除了它

logCh := make(chan string, 150)
go func() {
    for {
        msg, ok := <-logCh
        if ok {
            if f, err := os.OpenFile("./log.log", os.O_APPEND, os.ModeAppend); err != nil {
                panic(err)
            } else {
                logTime := time.Now().Format(time.RFC3339)
                if _, err := f.WriteString(logTime + " - " + msg); err != nil {
                    fmt.Print(err)
                }
                f.Close()
            }
        } else {
            fmt.Print("Channel closed! \n")
            break
        }
    }
}()
logCh:=make(chan字符串,150)
go func(){
为了{

msg,ok:=您需要添加
O_WRONLY
标志:

if f, err := os.OpenFile("./log.log", os.O_APPEND|os.O_WRONLY, os.ModeAppend); err != nil { /*[...]*/ }
为了解释,这里是
open
的linux文档:

参数标志必须包括以下访问模式之一: O_RDONLY、O_WRONLY或O_RDWR。这些请求打开文件读取- 分别为只读、只读或读/写

如果选中,您可以看到:

O_RDONLY                         = 0x0
O_RDWR                           = 0x2
O_WRONLY                         = 0x1
因此,默认情况下,您将获得一个只读文件描述符。

它用于我

之前的代码:

os.OpenFile(文件名、os.O_创建、os.O_追加、os.ModePerm)
出现错误:文件描述符不正确

然后我将os.O_WRONLY添加到函数中

以下代码:

os.OpenFile(文件名,os.O_创建| os.O_WRONLY | os.O_追加,os.ModePerm)

而且没有出现问题。

这似乎是windows和linux之间的差异。 在windows os.O上,APPEND意味着写访问,如syscall\u windows.go中的代码所示

if mode&O_APPEND != 0 {
    access &^= GENERIC_WRITE
    access |= FILE_APPEND_DATA
}
在linux中,openflags按原样传递给linux系统调用

因此,在DOS/WINDOWS中,您不需要显式地添加带有附加标志的写入标志(这是自DOS以来的默认行为) Go-in-linux确实需要添加额外的标志才能工作


(…但在我看来,它不应该需要这个标志,因为附加意味着我想写。我应该向golang报告吗?)

我确认我可以在我的计算机上复制。这解决了我的问题,除了我在包装器函数中的
os.O_WRONLY
方法中使用了
os.OpenFile
外,我从其他地方调用它并试图从它返回的文件中读取,但当然它被设置为只写,所以我得到了相同的错误。由chan修复转到
os.O_RDWR
。欢迎来到StackOverflow!所以你说在windows上只使用os.O_APPEND就足够了,但对于linux,你只需要显式地添加os.O_wrwrwr,对吗?请扩展你的答案,以帮助未来的访问者立即看到解决方案并调用示例(就像这段代码在Windows上工作,但在Linux上不工作,而且这段代码的行为也相同)@MaximSagaydachny是的,在Windows中,只需append标志就足够了(在帖子中更新),谢谢:)