Cómo comprobar si un archivo existe en C++

Jinku Hu 12 octubre 2023
Cómo comprobar si un archivo existe en C++

Este artículo introducirá métodos de C++ para comprobar si un determinado archivo existe en un directorio. Sin embargo, ten en cuenta que el siguiente tutorial está basado en la librería filesystem de C++ 17, que sólo está soportada en los nuevos compiladores.

Usa std::filesystem::exists para comprobar si un archivo existe en un directorio

El método exists toma una ruta como argumento y devuelve el valor booleano true si corresponde a un archivo o directorio existente. En el siguiente ejemplo, inicializamos un vector con nombres de archivo arbitrarios para comprobarlos en el sistema de archivos con las funciones exists. Ten en cuenta que el método existe sólo comprueba el directorio actual donde se encuentra el archivo ejecutable.

#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;
}

El código anterior puede ser reimplementado con el algoritmo STL for_Each, lo que proporcionará una mejor reutilización del 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;
}

El método exists puede ser más informativo si se combina con otras rutinas de librerías <filesystem> como: is_directory y is_regular_file. Generalmente, algunos métodos del sistema de archivos no distinguen entre archivos y directorios, pero podemos usar funciones específicas de comprobación de tipos de archivos para verificar los nombres de las rutas, como se muestra en el siguiente código de ejemplo:

#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;
}

Ahora consideremos un caso en el que queremos navegar a un directorio en particular y comprobar un nombre de archivo específico si existe. Para ello, necesitamos usar el método current_path, que devuelve el directorio actual si no se pasa ningún argumento, o puede cambiar a un directorio si se especifica el argumento path. No olvide cambiar la ruta del directorio y los nombres de los archivos según su sistema para verificar mejor la salida del 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;
}

También se puede comprobar qué permisos tiene el usuario actual sobre los archivos de un directorio mientras se itera a través de directory_iterator. El método status se usa para obtener permisos y almacenarlos en una clase especial llamada perms. Los permisos recuperados pueden ser mostrados con operaciones de bits en la estructura de perms. El siguiente ejemplo muestra la extracción de permisos de propietario solamente (ver la lista completa aquí).

#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

Artículo relacionado - C++ File