[c++17]std::filesystem


c++ filesystem

來源:
http://www.modernescpp.com/index.php/c-17-more-details-about-the-library
https://www.bfilipek.com/2017/08/cpp17-details-filesystem.html

Filesystem 概覽

c++ fielsystem 的模子是 boost的filesystem(2003年就出來了,為啥我不知道?);都是基於POSIX的。

三/四個核心部分:

  1. path object
  2. directory_entry
  3. Directory iterators
  4. Plus many supportive functions
    • getting information about the path
    • files manipulation: copy, move, create, symlinks
    • last write time
    • permissions
    • space/filesize

Working with the Path object

namespace fs = std::experimental::filesystem;

fs::path pathToShow("C:\\Windows\\system.ini");
cout << "exists() = " << fs::exists(pathToShow) << "\n"
     << "root_name() = " << pathToShow.root_name() << "\n"
     << "root_path() = " << pathToShow.root_path() << "\n"
     << "relative_path() = " << pathToShow.relative_path() << "\n"
     << "parent_path() = " << pathToShow.parent_path() << "\n"
     << "filename() = " << pathToShow.filename() << "\n"
     << "stem() = " << pathToShow.stem() << "\n"
     << "extension() = " << pathToShow.extension() << "\n";

輸出如下:

exists() = 1
root_name() = C:
root_path() = C:
relative_path() = Windows\system.ini
parent_path() = C:\Windows
filename() = system.ini
stem() = system
extension() = .ini
What’s great about the above code?

用起來很方便,還可以跨平台,太爽了。

還可以遍歷一個path:

int i = 0;
for (const auto& part : pathToShow)
    cout << "path part: " << i++ << " = " << part << "\n";

輸出:

path part: 0 = C:
path part: 1 =
path part: 2 = Windows
path part: 3 = system.ini

如何拼接path

兩個辦法: 用 operator /=, 或 operator +=.

/= - 添加一個文件夾
+= - 直接以字符串形式拼接到后面

fs::path p1("C:\\temp");
p1 /= "user";
p1 /= "data";
cout << p1 << "\n";

fs::path p2("C:\\temp\\");
p2 += "user";
p2 += "data";
cout << p2 << "\n";

輸出:

C:\temp\user\data
C:\temp\userdata

獲取文件大小

uintmax_t ComputeFileSize(const fs::path& pathToCheck)
{
    if (fs::exists(pathToCheck) &&
        fs::is_regular_file(pathToCheck))
    {
        auto err = std::error_code{};
        auto filesize = fs::file_size(pathToCheck, err);
        if (filesize != static_cast<uintmax_t>(-1))
            return filesize;
    }

    return static_cast<uintmax_t>(-1);
}

獲取最后修改時間

auto timeEntry = fs::last_write_time(entry);
time_t cftime = chrono::system_clock::to_time_t(timeEntry);
cout << std::asctime(std::localtime(&cftime));

額外說一下,以path為參數的函數大部分都有兩個版本:

  • 一個拋異常: filesystem_error
  • 一個返回錯誤碼: error_code (system specific)

遍歷目錄

兩種遍歷:

  • directory_iterator(非遞歸遍歷)
  • recursive_directory_iterator - (遞歸遍歷,遍歷順序未定義,每個文件或目錄只遍歷一次)

兩種遍歷都會忽略 '.' 和 '..'

void DisplayDirTree(const fs::path& pathToShow, int level)
{
    if (fs::exists(pathToShow) && fs::is_directory(pathToShow))
    {
        auto lead = std::string(level * 3, ' ');
        for (const auto& entry : fs::directory_iterator(pathToShow))
        {
            auto filename = entry.path().filename();
            if (fs::is_directory(entry.status()))
            {
                cout << lead << "[+] " << filename << "\n";
                DisplayDirTree(entry, level + 1);
                cout << "\n";
            }
            else if (fs::is_regular_file(entry.status()))
                DisplayFileInfo(entry, lead, filename);
            else
                cout << lead << " [?]" << filename << "\n";
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM