HOWTO · C++
Controlla se un file esiste in C++
Questo articolo introduce diversi modi per verificare se un file esiste in una directory C++
In questa pagina
Usa std::filesystem::exists per verificare se un percorso indica una voce del file system esistente. La funzione restituisce true sia per i file sia per le directory. L’esempio crea una piccola directory temporanea e un file, così il controllo dispone di un input autonomo; sostituisci file con il percorso che vuoi verificare nel tuo programma.
Usa std::filesystem::exists per verificare se un file esiste in una directory
Esegui questo esempio:
#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
La chiamata fs::exists(file) controlla il percorso che le viene passato: non cerca un file con lo stesso nome. In questo esempio, folder / "notes.txt" combina una directory scelta con un nome di file tramite std::filesystem::path, che gestisce il separatore di percorso appropriato per la piattaforma. Usa lo stesso schema con il percorso della directory che ti interessa quando il file si trova fuori dalla directory di lavoro corrente del processo.
Un percorso relativo come "notes.txt" viene risolto a partire dalla directory di lavoro corrente del processo, determinata dall’ambiente da cui è stato avviato il programma. Non viene risolto automaticamente a partire dalla directory che contiene l’eseguibile. Per conoscere la directory di lavoro corrente, chiama fs::current_path(); per modificarla per il processo, usa fs::current_path(path) e gestisci gli eventuali errori del file system. Se devi controllare una sola posizione, costruire un percorso a partire da una directory nota è in genere più chiaro.
exists indica se una voce è presente, ma non ne specifica il tipo. Usa fs::is_regular_file(path) se deve corrispondere soltanto un file regolare, oppure fs::is_directory(path) se ti aspetti una directory. Anche questi controlli potrebbero non fornire una risposta utilizzabile se il programma non può accedere al file system o se il percorso cambia durante l’ispezione. Se il codice deve distinguere queste situazioni, usa gli overload che accettano std::error_code e controlla l’errore separatamente dal valore booleano restituito.
Per esempio, std::error_code ec; const bool found = fs::exists(path, ec); consente di esaminare sia found sia ec: se il risultato è false e non ci sono errori, il percorso non è stato trovato; se invece ec contiene un errore, indica perché il controllo non è stato completato. L’overload senza argomento per il codice di errore segnala i problemi del file system lanciando un’eccezione. Scegli la versione con codice di errore se il programma deve continuare in presenza di problemi del file system previsti; altrimenti, la versione che lancia eccezioni rende più leggibile un controllo semplice. Inoltre, tra il controllo e una successiva apertura, il percorso potrebbe non riferirsi più alla stessa voce: considera quindi il risultato una risposta alla ricerca, non una garanzia che l’operazione successiva riesca.
L’esempio usa std::filesystem e crea i propri file temporanei di prova. Se non riesce a creare la directory o il file, stampa il messaggio di preparazione e restituisce uno stato diverso da zero. Alla normale conclusione, la protezione per la pulizia tenta di rimuovere la directory temporanea e ignora gli errori di pulizia. La verifica usa l’overload che lancia eccezioni: un’eccezione del file system non gestita che esce da main può terminare il programma senza garantire l’esecuzione del distruttore della protezione. Nel percorso normale, l’output consiste nelle due righe mostrate sopra; le eventuali etichette e i messaggi stampati dall’esempio restano in inglese.