Golang坏文件描述符
在go例程中尝试附加到日志文件时,我得到了一个错误的文件描述符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
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标志就足够了(在帖子中更新),谢谢:)