2015-11-22 3 views
9

Je reçois un mauvais descripteur de fichier lorsque j'essaie de l'ajouter à un fichier de consignation dans ma routine d'accès.Descripteur de fichier incorrect Golang

write ./log.log: bad file descriptor

Le fichier existe et a 666 pour les autorisations. Au début, je pensais que c'était peut-être parce que chacun essayait d'ouvrir le fichier en même temps. J'ai mis en place un mutex pour essayer d'éviter cela mais j'ai eu le même problème et je l'ai supprimé.

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

Je confirme que je peux reproduire sur mon ordinateur. – HectorJ

Répondre

22

Vous devez ajouter le drapeau O_WRONLY:

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

Pour expliquer, voici la documentation Linux Open: http://man7.org/linux/man-pages/man2/openat.2.html:

Les drapeaux argument doivent inclure un des éléments suivants modes d'accès: O_RDONLY, O_WRONLY ou O_RDWR. Ces requêtes ouvrent le fichier read- uniquement, en écriture seule ou en lecture/écriture, respectivement.

Si vous cochez /usr/local/go/src/syscall/zerrors_linux_amd64.go:660, vous pouvez voir que:

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

Donc, par défaut, vous obtenez un descripteur de fichier en lecture seule.

+0

Cela a résolu mon problème, sauf dans mon cas, j'avais 'os.O_WRONLY' dans la méthode' os.OpenFile' dans une fonction d'encapsuleur, et j'appelais cela d'ailleurs et j'essayais de lire à partir du fichier retourné, mais bien sûr il a été mis en écriture seulement, donc je recevais la même erreur. Correction en changeant à 'os.O_RDWR'. – Lansana