HOWTO · Csharp
Verifique se existe um arquivo em C#
O método File.Exists() pode ser usado para verificar se um arquivo existe em um caminho específico em C#.
Nesta página
Antes de o programa ler, gravar ou excluir um arquivo, muitas vezes ajuda saber se ele realmente está lá. O C# oferece essa verificação por meio de File.Exists, um método do namespace System.IO que testa um caminho e retorna uma resposta booleana. Este guia mostra como chamá-lo, como caminhos relativos e absolutos determinam o que é verificado, o que um resultado false realmente informa e como agir com base na resposta sem confiar nela além do devido.
Verifique se um arquivo existe com File.Exists
File.Exists é um método estático, portanto você o chama na própria classe File, e não em uma instância. Você passa um caminho como uma string, e ele retorna true quando o sistema operacional consegue confirmar um arquivo regular nesse caminho e false quando não consegue.
Execute este exemplo:
O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.
using System;
using System.IO;
class Program
{
static void Main()
{
string path = Path.Combine(Path.GetTempPath(), "delftstack-demo.txt");
File.WriteAllText(path, "demo content");
bool fileExists = File.Exists(path);
Console.WriteLine($"Does the file exist? {fileExists}");
File.Delete(path);
}
}
Saída:
Does the file exist? True
O programa cria um arquivo pequeno no diretório temporário do sistema, pergunta sobre ele a File.Exists e imprime a resposta, que é True porque o arquivo acabou de ser criado. Aponte path para o local que você precisar testar; a chamada permanece a mesma e o resultado é sempre um bool simples, pronto para uma instrução if ou para ser guardado em uma variável.
Escolha o caminho a verificar
A string que você passa determina qual local será examinado, portanto escolha-a com cuidado.
Um caminho absoluto identifica o arquivo por completo — C:\Data\report.txt no Windows ou /var/data/report.txt no Linux. Ele se refere ao mesmo local, não importa de onde o programa seja executado, portanto dê preferência a ele quando o local for fixo ou vier da configuração ou da entrada do usuário.
Um caminho relativo como report.txt ou logs/report.txt é resolvido em relação ao diretório de trabalho do processo, o valor de Environment.CurrentDirectory. Normalmente é a pasta em que o processo foi iniciado — não necessariamente a pasta que contém o executável — e outro código pode alterá-lo, portanto um caminho relativo pode apontar silenciosamente para um local diferente do esperado.
Execute este exemplo para ver o mesmo nome relativo resolver para dois lugares diferentes:
O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.
using System;
using System.IO;
class Program
{
static void Main()
{
string dir = Path.Combine(Path.GetTempPath(), "delftstack-cwd-demo");
Directory.CreateDirectory(dir);
File.WriteAllText(Path.Combine(dir, "delftstack-report-7f3a1c.txt"), "demo");
Console.WriteLine(File.Exists("delftstack-report-7f3a1c.txt"));
Directory.SetCurrentDirectory(dir);
Console.WriteLine(File.Exists("delftstack-report-7f3a1c.txt"));
Directory.SetCurrentDirectory(Path.GetTempPath());
File.Delete(Path.Combine(dir, "delftstack-report-7f3a1c.txt"));
Directory.Delete(dir);
}
}
Saída:
False
True
A primeira verificação procura o arquivo no diretório de trabalho original e não encontra nada. Depois que Directory.SetCurrentDirectory move o processo para a pasta que contém o arquivo, o mesmo nome relativo resolve para ele e a verificação retorna True.
Ao escrever caminhos do Windows em código-fonte C#, a barra invertida exige atenção apenas por causa da sintaxe de string, não porque o Windows exija separadores duplicados. Em uma string comum, \ inicia uma sequência de escape, portanto escreva "C:\\Data\\report.txt"; em uma string verbatim prefixada com @, escreva barras invertidas simples: @"C:\Data\report.txt". O .NET também aceita barras normais ("C:/Data/report.txt") no Windows e, no Linux e no macOS, / é o separador normal, portanto Path.Combine é a maneira mais portátil de montar caminhos.
Interprete o resultado e suas limitações
File.Exists responde a uma pergunta restrita: o sistema operacional consegue confirmar um arquivo neste caminho agora? Leia false como “não foi possível confirmar”, e não especificamente como “o arquivo está ausente”. O método também retorna false quando o caminho é null ou malformado, quando o caminho nomeia um diretório em vez de um arquivo (use Directory.Exists para pastas) e quando a própria verificação encontra problemas, como falta de permissão para percorrer as pastas.
Esses problemas são absorvidos pelo resultado false em vez de serem lançados, portanto um try/catch em torno de File.Exists quase nunca observará nada. Se o programa precisar saber por que um caminho falhou — para registrar, avisar o usuário ou decidir se deve tentar novamente — verifique você mesmo a condição específica ou simplesmente tente a operação real no arquivo e leia o erro que ela relata.
A chamada é síncrona e acessa o sistema de arquivos. Normalmente isso é rápido, mas pode demorar de forma perceptível em um compartilhamento de rede ou em um disco lento, portanto evite chamá-la em um loop apertado quando um único resultado armazenado for suficiente.
Use o resultado com segurança
Trate a resposta como um instantâneo, não como uma garantia. Entre a chamada a File.Exists e o momento em que você abre o arquivo, outro processo — ou outra thread do próprio programa — pode excluí-lo, movê-lo ou substituí-lo, e até if (File.Exists(path)) File.ReadAllText(path) ainda pode falhar.
O hábito robusto é agir sobre o arquivo e tratar o resultado da própria operação:
O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.
using System;
using System.IO;
class Program
{
static void Main()
{
string path = Path.Combine(Path.GetTempPath(), "delftstack-read-demo.txt");
File.WriteAllText(path, "hello from disk");
if (File.Exists(path))
{
try
{
Console.WriteLine(File.ReadAllText(path));
}
catch (IOException)
{
Console.WriteLine("The file could not be read.");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Access to the file was denied.");
}
}
File.Delete(path);
}
}
Saída:
hello from disk
Aqui File.Exists evita o trabalho de forma limpa quando não há nada, enquanto o try/catch em torno de File.ReadAllText cobre o que a verificação não consegue — um arquivo que desapareceu (manifestado como FileNotFoundException, um tipo de IOException), um arquivo bloqueado por outro processo ou acesso negado. Quando seu único objetivo é ler o arquivo, você pode dispensar a verificação e deixar o catch tratar a ausência, o que elimina totalmente a condição de corrida. Mantenha File.Exists para decisões em que a resposta booleana basta por si só: exibir uma mensagem, escolher entre criar e abrir um arquivo ou pular uma etapa de limpeza.