Como verificar se um arquivo existe em C++

Jinku Hu 12 outubro 2023
Como verificar se um arquivo existe em C++

Este artigo introduzirá métodos C++ para verificar se um determinado arquivo existe em um diretório. Observe, no entanto, que o seguinte tutorial é baseado na biblioteca C++ 17 filesystem, que só é suportada em novos compiladores.

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

O método exists toma um caminho como argumento e retorna o valor booleano true se corresponder a um arquivo ou diretório existente. No exemplo a seguir, inicializamos um vetor com nomes de arquivos arbitrários para verificá-los no sistema de arquivos com funções exists. Esteja ciente de que o método exists só verifica o diretório atual onde o arquivo executável está localizado.

#include <filesystem>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::filesystem::exists;

int main() {
  vector<string> files_to_check = {"main.cpp", "Makefile", "hello-world"};

  for (const auto &file : files_to_check) {
    exists(file) ? cout << "Exists\n" : cout << "Doesn't exist\n";
  }

  return EXIT_SUCCESS;
}

O código acima pode ser reimplementado com o algoritmo STL for_Each, o que proporcionará uma melhor reusabilidade do código:

#include <filesystem>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::filesystem::exists;

int main() {
  vector<string> files_to_check = {"main.cpp", "Makefile", "hello-world"};

  auto check = [](const auto &file) {
    exists(file) ? cout << "Exists\n" : cout << "Doesn't exist\n";
  };

  for_each(files_to_check.begin(), files_to_check.end(), check);

  return EXIT_SUCCESS;
}

O método exists pode ser mais informativo se combinado com outros <filesystem> rotinas de biblioteca como: is_directory e is_regular_file. Geralmente, alguns métodos de sistema de arquivos não fazem distinção entre arquivos e diretórios, mas podemos utilizar funções específicas de verificação de tipo de arquivo para verificar nomes de caminho, como mostrado no seguinte exemplo de código:

#include <filesystem>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::filesystem::exists;
using std::filesystem::is_directory;
using std::filesystem::is_regular_file;

int main() {
  vector<string> files_to_check = {"main.cpp", "Makefile", "hello-world"};

  for (const auto &file : files_to_check) {
    if (exists(file)) {
      if (is_directory(file)) cout << "Directory exists\n";
      if (is_regular_file(file))
        cout << "File exists\n";
      else
        cout << "Exists\n";
    } else {
      cout << "Doesn't exist\n";
    };
  };

  return EXIT_SUCCESS;
}

Agora vamos considerar um caso quando queremos navegar para um determinado diretório e verificar um nome de arquivo específico, se ele existe. Para isso, precisamos utilizar o método current_path, que retorna o diretório atual se nenhum argumento for passado, ou pode mudar o diretório de trabalho atual para o caminho especificado, se o argumento for dado. Não esqueça de mudar o caminho do diretório e os nomes dos arquivos com base em seu sistema para verificar melhor a saída do programa:

#include <filesystem>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::filesystem::current_path;
using std::filesystem::exists;
using std::filesystem::is_directory;
using std::filesystem::is_regular_file;

int main() {
  vector<string> files_to_check = {"main.cpp", "Makefile", "hello-world"};
  current_path("../");
  for (const auto &file : files_to_check) {
    exists(file) ? cout << "Exists\n" : cout << "Doesn't exist\n";
  }

  return EXIT_SUCCESS;
}

Também é possível verificar quais permissões o usuário atual tem em arquivos de um diretório enquanto a iteração é feita através do directory_iterator. O método status é utilizado para obter permissões e armazená-las em uma classe especial chamada perms. As permissões recuperadas podem ser exibidas com operações bitwise na estrutura de perms. O exemplo a seguir mostra apenas a extração das permissões do proprietário (veja a lista completa aqui).

#include <filesystem>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::filesystem::directory_iterator;
using std::filesystem::exists;
using std::filesystem::perms;

using std::string;

int main() {
  vector<std::filesystem::perms> f_perm;
  string path = "../";

  for (const auto& file : directory_iterator(path)) {
    cout << file << " - ";
    cout << ((file.status().permissions() & perms::owner_read) != perms::none
                 ? "r"
                 : "-")
         << ((file.status().permissions() & perms::owner_write) != perms::none
                 ? "w"
                 : "-")
         << ((file.status().permissions() & perms::owner_exec) != perms::none
                 ? "x"
                 : "-")
         << endl;
  }
  cout << endl;
  return EXIT_SUCCESS;
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artigo relacionado - C++ File