HOWTO · C++

Como verificar se um arquivo existe em C++

Este artigo introduz várias maneiras de verificar se um arquivo existe em um diretório C++

Nesta página

Use std::filesystem::exists para verificar se um caminho corresponde a uma entrada existente no sistema de arquivos. A função retorna true tanto para arquivos quanto para diretórios. O exemplo abaixo cria um diretório temporário pequeno e um arquivo para que a verificação tenha uma entrada autossuficiente; substitua file pelo caminho que seu programa precisa verificar.

Use std::filesystem::exists para verificar se um arquivo existe em um diretório

Execute este exemplo:

#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>

int main() {
  namespace fs = std::filesystem;
  const auto unique = std::chrono::steady_clock::now().time_since_epoch().count();
  const fs::path folder = fs::temp_directory_path() /
                          ("cpp-exists-" + std::to_string(unique));
  std::error_code ec;
  if (!fs::create_directory(folder, ec) || ec) {
    std::cout << "Could not prepare example\n";
    return 1;
  }

  struct cleanup_guard {
    fs::path path;
    ~cleanup_guard() {
      std::error_code cleanup_error;
      fs::remove_all(path, cleanup_error);
    }
  } cleanup{folder};

  const fs::path file = folder / "notes.txt";
  {
    std::ofstream output(file);
    if (!output) {
      std::cout << "Could not prepare example\n";
      return 1;
    }
  }

  std::cout << (fs::exists(file) ? "Path exists\n" : "Path does not exist\n");
  std::cout << (fs::is_regular_file(file) ? "It is a regular file\n"
                                          : "It is not a regular file\n");

}
Path exists
It is a regular file

A chamada fs::exists(file) verifica o caminho recebido. Ela não procura um arquivo com o mesmo nome. Neste exemplo, folder / "notes.txt" combina um diretório escolhido com um nome de arquivo usando std::filesystem::path, que trata o separador de caminhos da plataforma. Use o mesmo padrão com o caminho do seu diretório quando o destino estiver fora do diretório de trabalho atual do processo.

Um caminho relativo, como "notes.txt", é resolvido a partir do diretório de trabalho atual do processo, definido pelo ambiente em que o programa é iniciado. Ele não é resolvido automaticamente a partir do diretório que contém o executável. Para consultar o diretório de trabalho atual, chame fs::current_path(); para alterá-lo no processo, use fs::current_path(path) e trate qualquer erro de sistema de arquivos informado. Se você precisa verificar apenas um local, construir o caminho a partir de um diretório conhecido costuma ser mais claro.

exists informa se uma entrada está presente, mas não qual é o tipo dela. Use fs::is_regular_file(path) quando somente um arquivo regular deve corresponder, ou fs::is_directory(path) quando você espera um diretório. Essas verificações também podem não fornecer uma resposta utilizável se o programa não tiver acesso ao sistema de arquivos ou se o caminho mudar durante a inspeção. Para distinguir esses casos no código, use as sobrecargas que aceitam std::error_code e examine o erro separadamente do valor booleano retornado.

Por exemplo, std::error_code ec; const bool found = fs::exists(path, ec); permite examinar found e ec: um resultado falso sem erro significa que o caminho não foi encontrado; se houver um erro, ele informa por que não foi possível concluir a verificação. A sobrecarga sem argumento de código de erro informa falhas do sistema de arquivos lançando uma exceção. Escolha a forma com código de erro quando o código precisar continuar diante de problemas esperados no sistema de arquivos; caso contrário, a forma que lança exceções mantém uma verificação simples e legível. O caminho também pode deixar de apontar para a mesma entrada entre a verificação e uma abertura posterior. Portanto, use o resultado como resposta à consulta, não como garantia de que a operação seguinte terá êxito.

O exemplo usa std::filesystem e cria seu próprio conjunto temporário de teste. Se a preparação do diretório ou do arquivo falhar, ele imprime a mensagem de preparação e retorna um status diferente de zero. A proteção de limpeza tenta remover o diretório temporário nas saídas normais, e erros de limpeza são ignorados. A consulta usa a sobrecarga que lança exceções; portanto, se uma exceção de sistema de arquivos não tratada escapar de main, o programa poderá terminar sem garantir que o destrutor da proteção seja executado. No fluxo normal, a saída são as duas linhas mostradas acima. Os textos literais exibidos pelo exemplo permanecem em inglês, pois os blocos são preservados sem alterações.