Bagikan melalui


Navigasi Sistem File

Header <filesystem> mengimplementasikan C++ File System Technical Specification ISO/IEC TS 18822:2015 (Draf akhir: ISO/IEC JTC 1/SC 22/WG 21 N4100) dan memiliki jenis dan fungsi yang memungkinkan Anda menulis kode independen platform untuk menavigasi sistem file. Karena lintas platform, ini berisi API yang tidak relevan untuk sistem Windows. Misalnya, is_fifo(const path&) selalu kembali false pada Windows.

Gambaran Umum

<filesystem> Gunakan API untuk tugas-tugas berikut:

  • iterasi melalui file dan direktori di bawah jalur tertentu

  • mendapatkan informasi tentang file termasuk waktu yang dibuat, ukuran, ekstensi, dan direktori akar

  • menyusun, menguraikan, dan membandingkan jalur

  • membuat, menyalin, dan menghapus direktori

  • menyalin dan menghapus file

Untuk informasi selengkapnya tentang IO File menggunakan Pustaka Standar, lihat Pemrograman iostream.

Jalur

Membuat dan menyusun jalur

Jalur di Windows (karena XP) disimpan secara asli di Unicode. Kelas path secara otomatis melakukan semua konversi string yang diperlukan. Ini menerima argumen array karakter lebar dan sempit, dan jenis dan std::wstring yang std::string diformat sebagai UTF8 atau UTF16. Kelas juga path secara otomatis menormalkan pemisah jalur. Anda dapat menggunakan garis miring tunggal sebagai pemisah direktori dalam argumen konstruktor. Pemisah ini memungkinkan Anda menggunakan string yang sama untuk menyimpan jalur di lingkungan Windows dan 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.

Untuk menggabungkan dua jalur, Anda dapat menggunakan operator dan kelebihan beban/, yang dianalogikan dengan + operator dan += pada std::string dan std::wstring./= Objek path akan dengan mudah menyediakan pemisah jika Anda tidak.

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

Memeriksa jalur

Kelas jalur memiliki beberapa metode yang mengembalikan informasi tentang berbagai bagian jalur itu sendiri. Informasi ini berbeda dari informasi tentang entitas sistem file yang mungkin dirujuknya. Anda bisa mendapatkan root, jalur relatif, nama file, ekstensi file, dan banyak lagi. Anda dapat melakukan iterasi pada objek jalur untuk memeriksa semua folder dalam hierarki. Contoh berikut menunjukkan cara melakukan iterasi melalui objek jalur. Dan, cara mengambil informasi tentang bagian-bagiannya.

// 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);
}

Kode menghasilkan output ini:

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

Membandingkan jalur

Kelas path membebani operator perbandingan yang sama dengan std::string dan std::wstring. Saat Membandingkan dua jalur, Anda membuat perbandingan string setelah pemisah dinormalisasi. Jika garis miring berikutnya (atau garis miring terbelakang) hilang, garis miring tersebut tidak ditambahkan, dan itu memengaruhi perbandingan. Contoh berikut menunjukkan bagaimana nilai jalur dibandingkan:

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

Untuk menjalankan kode ini, tempelkan ke contoh lengkap di atas sebelumnya main dan batalkan komentar baris yang memanggilnya di utama.

Mengonversi antara jenis jalur dan string

Objek path secara implisit dapat dikonversi ke std::wstring atau std::string. Ini berarti Anda dapat meneruskan jalur ke fungsi seperti , seperti wofstream::openyang ditunjukkan dalam contoh ini:

// 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

Iterasi direktori dan file

Header <filesystem> menyediakan directory_iterator jenis untuk melakukan iterasi melalui direktori tunggal, dan recursive_directory_iterator kelas untuk melakukan iterasi secara rekursif melalui direktori dan subdirektorinya. Setelah Anda membuat iterator dengan meneruskannya objek path , iterator menunjuk ke directory_entry pertama di jalur. Buat iterator akhir dengan memanggil konstruktor default.

Saat melakukan iterasi melalui direktori, ada beberapa jenis item yang mungkin Anda temukan. Item-item ini termasuk direktori, file, tautan simbolis, file soket, dan lainnya. mengembalikan directory_iterator itemnya sebagai directory_entry objek.