2015-11-22 2 views
9

Я получаю плохой файловый дескриптор при попытке добавить файл журнала в мою рутину.Golang bad file descriptor

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 
     } 
    } 
}() 
+0

Я подтверждаю, что могу воспроизвести на своем компьютере. – HectorJ

ответ

22

Вы должны добавить O_WRONLY флаг:

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

Чтобы объяснить, вот документация Linux для открытых: http://man7.org/linux/man-pages/man2/openat.2.html:

Аргумент флаги должны включать в себя одно из следующих действий режимы доступа: O_RDONLY, O_WRONLY или O_RDWR. Эти запросы открывают только файл read- , только для записи или чтения/записи.

Если вы проверяете /usr/local/go/src/syscall/zerrors_linux_amd64.go:660, вы можете увидеть, что:

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

Так по умолчанию вы получаете только для чтения дескриптор файла.

+0

Это решило мою проблему, кроме как в моем случае у меня был 'os.O_WRONLY' в методе' os.OpenFile' в функции-обертки, и я звонил из другого места и пытался прочитать из возвращаемого файла, но, конечно, он был настроен только на запись, поэтому я получал ту же ошибку. Исправлено путем изменения на 'os.O_RDWR'. – Lansana

Смежные вопросы