Condividi tramite


Esplorazione del file system

L'intestazione <filesystem> implementa la specifica tecnica del file system C++ ISO/IEC TS 18822:2015 (bozza finale: ISO/IEC JTC 1/SC 22/WG 21 N4100) e include tipi e funzioni che consentono di scrivere codice indipendente dalla piattaforma per l'esplorazione del file system. Poiché è multipiattaforma, contiene API non rilevanti per i sistemi Windows. Ad esempio, restituisce is_fifo(const path&) false sempre windows.

Panoramica

Usare le <filesystem> API per le attività seguenti:

  • eseguire l'iterazione su file e directory in un percorso specificato

  • ottenere informazioni sui file inclusi data e ora di creazione, dimensioni, estensione e directory principale

  • comporre, scomporre e confrontare percorsi

  • creare, copiare ed eliminare directory

  • copiare ed eliminare i file

Per altre informazioni sull'I/O file con la libreria standard, vedere la Programmazione di iostream.

Percorsi

Costruzione e composizione di percorsi

I percorsi in Windows (a partire da XP) vengono archiviati in modo nativo in formato Unicode. La path classe esegue automaticamente tutte le conversioni di stringhe necessarie. Accetta argomenti di matrici di caratteri wide e narrow e entrambi std::string i tipi e std::wstring formattati come UTF8 o UTF16. La classe path normalizza automaticamente anche i separatori del percorso. È possibile usare una singola barra come separatore di directory in argomenti del costruttore. Questo separatore consente di usare le stesse stringhe per archiviare i percorsi in ambienti Windows e UNIX:

path pathToDisplay(L"/FileSystemTest/SubDir3");     // OK!
path pathToDisplay2(L"\\FileSystemTest\\SubDir3");  // Still OK as always
path pathToDisplay3(LR"(\FileSystemTest\SubDir3)"); // Raw string literals are OK, too.

Per concatenare due percorsi, è possibile usare gli operatori / e /= in rapporto di overload, che sono analoghi agli operatori + e += in std::string e std::wstring. In caso contrario, l'oggetto path fornirà i separatori.

path myRoot("C:/FileSystemTest");  // no trailing separator, no problem!
myRoot /= path("SubDirRoot");      // C:/FileSystemTest/SubDirRoot

Esame dei percorsi

La classe path include diversi metodi che restituiscono informazioni sulle varie parti del percorso stesso. Queste informazioni sono distinte dalle informazioni sull'entità del file system a cui può fare riferimento. È possibile ottenere la radice, il percorso relativo, il nome del file, l'estensione del file e molto altro. È possibile eseguire l'iterazione su un oggetto path per esaminare tutte le cartelle nella gerarchia. Nell'esempio seguente viene illustrato come eseguire l'iterazione su un oggetto path. E come recuperare informazioni sulle sue parti.

// filesystem_path_example.cpp
// compile by using: /EHsc /W4 /permissive- /std:c++17 (or later)
#include <string>
#include <iostream>
#include <sstream>
#include <filesystem>

using namespace std;
using namespace std::filesystem;

wstring DisplayPathInfo()
{
    // This path may or may not refer to an existing file. We are
    // examining this path string, not file system objects.
    path pathToDisplay(L"C:/FileSystemTest/SubDir3/SubDirLevel2/File2.txt ");

    wostringstream wos;
    int i = 0;
    wos << L"Displaying path info for: " << pathToDisplay << endl;
    for (path::iterator itr = pathToDisplay.begin(); itr != pathToDisplay.end(); ++itr)
    {
        wos << L"path part: " << i++ << L" = " << *itr << endl;
    }

    wos << L"root_name() = " << pathToDisplay.root_name() << endl
        << L"root_path() = " << pathToDisplay.root_path() << endl
        << L"relative_path() = " << pathToDisplay.relative_path() << endl
        << L"parent_path() = " << pathToDisplay.parent_path() << endl
        << L"filename() = " << pathToDisplay.filename() << endl
        << L"stem() = " << pathToDisplay.stem() << endl
        << L"extension() = " << pathToDisplay.extension() << endl;

    return wos.str();
}

int main()
{
    wcout << DisplayPathInfo() << endl;
    // wcout << ComparePaths() << endl; // see following example
    wcout << endl << L"Press Enter to exit" << endl;
    wstring input;
    getline(wcin, input);
}

Il codice produce il seguente output:

Displaying path info for: C:\FileSystemTest\SubDir3\SubDirLevel2\File2.txt
path part: 0 = C:
path part: 1 = \
path part: 2 = FileSystemTest
path part: 3 = SubDir3
path part: 4 = SubDirLevel2
path part: 5 = File2.txt
root_name() = C:
root_path() = C:\
relative_path() = FileSystemTest\SubDir3\SubDirLevel2\File2.txt
parent_path() = C:\FileSystemTest\SubDir3\SubDirLevel2
filename() = File2.txt
stem() = File2
extension() = .txt

Confronto tra percorsi

La classe path è in rapporto di overload con gli stessi operatori di confronto di std::string e std::wstring. Quando si confrontano due percorsi, si esegue un confronto tra stringhe dopo che i separatori sono stati normalizzati. Se manca una barra finale (o barra rovesciata), non viene aggiunta e ciò influisce sul confronto. L'esempio seguente dimostra come confrontare i valori di percorso:

wstring ComparePaths()
{
    path p0(L"C:/Documents");                 // no trailing separator
    path p1(L"C:/Documents/");                // p0 < p1
    path p2(L"C:/Documents/2013/");           // p1 < p2
    path p3(L"C:/Documents/2013/Reports/");   // p2 < p3
    path p4(L"C:/Documents/2014/");           // p3 < p4
    path p5(L"D:/Documents/2013/Reports/");   // p4 < p5

    wostringstream wos;
    wos << boolalpha <<
        p0.wstring() << L" < " << p1.wstring() << L": " << (p0 < p1) << endl <<
        p1.wstring() << L" < " << p2.wstring() << L": " << (p1 < p2) << endl <<
        p2.wstring() << L" < " << p3.wstring() << L": " << (p2 < p3) << endl <<
        p3.wstring() << L" < " << p4.wstring() << L": " << (p3 < p4) << endl <<
        p4.wstring() << L" < " << p5.wstring() << L": " << (p4 < p5) << endl;
    return wos.str();
}
C:\Documents < C:\Documents\: true
C:\Documents\ < C:\Documents\2013\: true
C:\Documents\2013\ < C:\Documents\2013\Reports\: true
C:\Documents\2013\Reports\ < C:\Documents\2014\: true
C:\Documents\2014\ < D:\Documents\2013\Reports\: true

Per eseguire questo codice, incollarlo nell'esempio completo sopra prima di main e rimuovere il commento dalla riga che chiama tale codice.

Conversione tra tipi di stringa e percorso

Un oggetto path è convertibile in modo implicito in un oggetto std::wstring o std::string. Ciò significa che è possibile passare un percorso a funzioni come wofstream::open, come illustrato in questo esempio:

// filesystem_path_conversion.cpp
// compile by using: /EHsc /W4 /permissive- /std:c++17 (or later)
#include <string>
#include <iostream>
#include <fstream>
#include <filesystem>

using namespace std;
using namespace std::filesystem;

int main()
{
    const wchar_t* p{ L"C:/Users/Public/Documents" };
    path filePath(p);

    filePath /= L"NewFile.txt";

    // Open, write to, and close the file.
    wofstream writeFile(filePath, ios::out);  // implicit conversion
    writeFile << L"Lorem ipsum\nDolor sit amet";
    writeFile.close();

    // Open, read, and close the file.
    wifstream readFile;
    wstring line;
    readFile.open(filePath);  // implicit conversions
    wcout << L"File " << filePath << L" contains:" << endl;
    while (readFile.good())
    {
        getline(readFile, line);
        wcout << line << endl;
    }
    readFile.close();

    wcout << endl << L"Press Enter to exit" << endl;
    wstring input;
    getline(wcin, input);
}
File C:\Users\Public\Documents\NewFile.txt contains:
Lorem ipsum
Dolor sit amet

Press Enter to exit

Iterazione di directory e file

L'intestazione <filesystem> fornisce il directory_iterator tipo per scorrere le singole directory e la recursive_directory_iterator classe per scorrere in modo ricorsivo una directory e le relative sottodirectory. Dopo aver creato un iteratore passandovi un oggetto path , l'iteratore punta al primo oggetto directory_entry nel percorso. Creare l'iteratore finale chiamando il costruttore predefinito.

Durante l'iterazione di una directory, è possibile individuare diversi tipi di elementi. Questi elementi includono directory, file, collegamenti simbolici, file socket e altri. Restituisce directory_iterator gli elementi come directory_entry oggetti .