web-dev-qa-db-ja.com

Golangの不正なファイル記述子

Goルーチン内でログファイルに追加しようとすると、不良ファイル記述子が取得されます。

write ./log.log: bad file descriptor

ファイルが存在し、許可のために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
        }
    }
}()
17
Jared Mackey

O_WRONLYフラグを追加する必要があります。

if f, err := os.OpenFile("./log.log", os.O_APPEND|os.O_WRONLY, os.ModeAppend); err != nil { /*[...]*/ }

説明のために、openのLinuxドキュメントを以下に示します。 http://man7.org/linux/man-pages/man2/openat.2.html

引数フラグには、O_RDONLY、O_WRONLY、またはO_RDWRのいずれかのアクセスモードを含める必要があります。これらのリクエストは、それぞれファイルを読み取り専用、書き込み専用、または読み取り/書き込みで開きます。

/usr/local/go/src/syscall/zerrors_linux_AMD64.go:660を確認すると、次のことがわかります。

O_RDONLY                         = 0x0
O_RDWR                           = 0x2
O_WRONLY                         = 0x1

そのため、デフォルトでは読み取り専用のファイル記述子を取得します。

39
HectorJ

それは私のために使用しました

前のコード:

os.OpenFile(fileName, os.O_CREATE|os.O_APPEND, os.ModePerm)

エラーが発生しました:不正なファイル記述子、

次に、os.O_WRONLYを関数に追加します

後のコード:

os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm)

そして、それは問題を起こさなかった。

0
jack wu