Como verificar se existe um arquivo no Go?

A biblioteca padrão do Go não tem uma function destinada apenas a verificar se existe ou não um arquivo (como o os.path.exists do Python). Qual é a maneira idiomática de fazer isso?

Para verificar se não existe um arquivo, equivalente ao Python if not os.path.exists(filename) :

 if _, err := os.Stat("/path/to/whatever"); os.IsNotExist(err) { // path/to/whatever does not exist } 

Para verificar se existe um arquivo, equivalente ao do Python if os.path.exists(filename) :

 if _, err := os.Stat("/path/to/whatever"); err == nil { // path/to/whatever exists } // the path does not exist or some error occurred. 

Resposta de Caleb Spare postada na lista de discussão gonuts .

[…] Não é realmente necessário com muita freqüência e […] usar os.Stat é bastante fácil para os casos em que é necessário.

[…] Por exemplo: se você for abrir o arquivo, não há razão para verificar se existe primeiro. O arquivo pode desaparecer entre a verificação e a abertura e, de qualquer forma, você precisará verificar o erro os.Open . Então, você simplesmente chama os.IsNotExist(err) depois de tentar abrir o arquivo e lidar com a inexistência dele (se isso requer tratamento especial).

[…] Você não precisa verificar os caminhos existentes (e você não deveria).

  • os.MkdirAll funciona se os caminhos já existem ou não. (Além disso, você precisa verificar o erro dessa chamada).

  • Em vez de usar os.Create , você deve usar os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) . Dessa forma, você receberá um erro se o arquivo já existir. Também isso não tem uma condição de corrida com outra coisa fazendo o arquivo, ao contrário da sua versão, que verifica a existência de antemão.

Extraído de: https://groups.google.com/forum/#!msg/golang-nuts/Ayx-BMNdMFo/4rL8FFHr8v4J

Você deve usar as os.Stat() e os.IsNotExist() como no exemplo a seguir:

 // Exists reports whether the named file or directory exists. func Exists(name string) bool { if _, err := os.Stat(name); err != nil { if os.IsNotExist(err) { return false } } return true } 

O exemplo é extraído daqui .

  _, err := os.Stat(file) if err == nil { log.Printf("file %s exists", file) } else if os.IsNotExist(err) { log.Printf("file %s not exists", file) } else { log.Printf("file %s stat error: %v", file, err) } 

O exemplo por user11617 está incorreto; ele relatará que o arquivo existe mesmo nos casos em que não existe, mas houve um erro de algum outro tipo.

A assinatura deve ser Exists (string) (bool, error). E então, quando isso acontece, os sites de chamadas não são melhores.

O código que ele escreveu seria melhor como:

 func Exists(name string) bool { _, err := os.Stat(name) return !os.IsNotExist(err) } 

Mas sugiro isso em vez disso:

 func Exists(name string) (bool, error) { err := os.Stat(name) if os.IsNotExist(err) { return false, nil } return err != nil, err } 

O exemplo da function:

 func file_is_exists(f string) bool { _, err := os.Stat(f) if os.IsNotExist(err) { return false } return err == nil } 

Vamos dar uma olhada em alguns aspectos primeiro, tanto a function fornecida pelo pacote os de golang não são utilitários, mas os verificadores de erros, o que eu quero dizer com isso é que eles são apenas um wrapper para lidar com erros na plataforma cruzada.

Então, basicamente, se os.Stat se esta function não dá nenhum erro que significa que o arquivo é existente se você precisa verificar que tipo de erro é, aqui vem o uso dessas duas funções os.IsNotExist e os.IsExist .

Isso pode ser entendido como a Stat do arquivo jogando erro porque ele não existe ou está jogando erro porque existe e há algum problema com ele.

O parâmetro que essas funções executam é do tipo error , embora você possa ser passível de nil , mas não faria sentido.

Isso também aponta para o fato de que IsExist is not same as !IsNotExist , eles são duas coisas diferentes.

Então, agora, se você quiser saber se um determinado arquivo existe, prefiro que a melhor maneira seja:

 if _, err := os.Stat(path/to/file); !os.IsNotExist(err){ //TODO }