Controlla se un file esiste in C++

Jinku Hu 12 ottobre 2023
Controlla se un file esiste in C++

Questo articolo introdurrà i metodi C++ per verificare se un determinato file esiste in una directory. Nota, tuttavia, il seguente tutorial è basato sulla libreria C++ 17 filesystem, che è supportata solo nei nuovi compilatori.

Usa std::filesystem::exist per controllare se un file esiste in una directory

Il metodo exists accetta un percorso come argomento e restituisce il valore booleano true se corrisponde a un file o una directory esistente. Nel seguente esempio, inizializziamo un vettore con nomi di file arbitrari per controllarli nel filesystem con le funzioni exists. Tieni presente che il metodo esiste controlla solo la directory corrente in cui si trova il file eseguibile.

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

Il codice sopra può essere reimplementato con l’algoritmo STL for_Each, che fornirà una migliore riusabilità del codice:

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

Il metodo exists può essere più informativo se combinato con altre routine di libreria <filesystem> come: is_directory e is_regular_file. In generale, alcuni metodi del filesystem non distinguono tra file e directory, ma possiamo usare specifiche funzioni di controllo del tipo di file per verificare i nomi dei percorsi, come mostrato nel seguente codice di esempio:

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

Consideriamo ora un caso in cui vogliamo navigare in una directory particolare e verificare se esiste un nome di file specifico. Per fare questo, dobbiamo usare il metodo current_path, che restituisce la directory corrente se non viene passato alcun argomento, oppure può cambiare la directory di lavoro corrente nel percorso specificato se viene fornito un argomento. Non dimenticare di modificare il percorso della directory ei nomi dei file in base al tuo sistema per verificare meglio l’output del programma:

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

Possiamo anche controllare quali permessi ha l’utente corrente sui file in una directory durante l’iterazione attraverso directory_iterator. Il metodo status viene utilizzato per ottenere i permessi e memorizzarli in una classe speciale chiamata perms. I permessi recuperati possono essere visualizzati con operazioni bit per bit sulla struttura perms. L’esempio seguente mostra solo l’estrazione dei permessi di proprietario (vedi l’lista completo qui).

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

Articolo correlato - C++ File