std::filesystem
是 C++17 中引入的标准库,用于处理文件系统操作。它提供了一组类和函数,用于执行文件和目录的创建、删除、遍历、重命名、复制等操作,以及获取文件和目录的属性信息。
std::filesystem::path 核心概念解释
std::filesystem::path
类用于表示文件系统路径。它提供了一组函数,用于获取路径的各个部分,以及将路径转换为字符串。
该对象把 linux
与 windows
中的路径进行统一的封装,规避掉了不同系统下的路径分隔符不同的问题。
该对象可以方便的通过 std::string
进行构造,可以方便的转换为 std::string
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p1("C:\\Windows\\System32\\drivers\\etc\\hosts"); std::filesystem::path p2("C:/Windows/System32/drivers/etc/hosts"); std::filesystem::path p3("C:", std::filesystem::path::format::generic_format); std::filesystem::path p4("Windows/System32/drivers/etc/hosts", std::filesystem::path::format::generic_format); std::filesystem::path p5("hosts", std::filesystem::path::format::generic_format); std::filesystem::path p6("C:\\Windows\\System32\\drivers\\etc\\hosts", std::filesystem::path::format::native_format); std::filesystem::path p7("C:/Windows/System32/drivers/etc/hosts", std::filesystem::path::format::native_format); std::filesystem::path p8("C:", std::filesystem::path::format::native_format); std::filesystem::path p9("Windows/System32/drivers/etc/hosts", std::filesystem::path::format::native_format); std::filesystem::path p10("hosts", std::filesystem::path::format::native_format);
std::cout << p1 << std::endl; std::cout << p2 << std::endl; std::cout << p3 << std::endl; std::cout << p4 << std::endl; std::cout << p5 << std::endl; std::cout << p6 << std::endl; std::cout << p7 << std::endl; std::cout << p8 << std::endl; std::cout << p9 << std::endl; std::cout << p10 << std::endl;
std::cout << p1.string() << std::endl; std::cout << p2.string() << std::endl; std::cout << p3.string() << std::endl; std::cout << p4.string() << std::endl; std::cout << p5.string() << std::endl; std::cout << p6.string() << std::endl; std::cout << p7.string() << std::endl; std::cout << p8.string() << std::endl; std::cout << p9.string() << std::endl; std::cout << p10.string() << std::endl;
return 0; }
|
使用场景
获取当前路径
1 2 3 4 5 6 7 8 9 10 11 12
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p = std::filesystem::current_path(); std::cout << p << std::endl;
auto str = p.str(); std::cout << str << std::endl; return 0; }
|
获取绝对路径
1 2 3 4 5 6 7 8 9 10 11 12
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p = std::filesystem::absolute("hosts"); std::cout << p << std::endl;
auto str = p.str(); std::cout << str << std::endl; return 0; }
|
判断文件或文件夹是否存在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p("hosts"); if (std::filesystem::exists(p)) { std::cout << "exists" << std::endl; } else { std::cout << "not exists" << std::endl; } return 0; }
|
创建文件夹
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p("test"); if (std::filesystem::create_directories(p)) { std::cout << "create directory success" << std::endl; } else { std::cout << "create directory failed" << std::endl; } return 0; }
|
std::filesystem::create_directory
与 std::filesystem::create_directories
的区别
std::filesystem::create_directory
用于创建单个目录,如果目录已经存在,则函数会抛出 std::filesystem::filesystem_error
异常。
std::filesystem::create_directories
用于创建多级目录,如果目录已经存在,则函数不会抛出异常。
因此,如果你需要创建多级目录,可以使用 std::filesystem::create_directories
,如果你只需要创建单个目录,则可以使用 std::filesystem::create_directory
。
创建文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p("test.txt"); if (std::filesystem::create_directory(p)) { std::cout << "create file success" << std::endl; } else { std::cout << "create file failed" << std::endl; } return 0; }
|
获取当前磁盘容量
1 2 3 4 5 6 7 8 9 10 11 12
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p("C:"); std::filesystem::space_info info = std::filesystem::space(p); std::cout << "capacity: " << info.capacity << std::endl; std::cout << "free: " << info.free << std::endl; std::cout << "available: " << info.available << std::endl; return 0; }
|
获取文件大小
1 2 3 4 5 6 7 8 9
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p("hosts"); std::cout << "file size: " << std::filesystem::file_size(p) << std::endl; return 0; }
|
获取文件夹下所有文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <iostream> #include <vector> #include <regex> #include <string> #include <filesystem> #include <ranges> #include <algorithm>
std::vector<std::string> get_directory_files(const std::string& path, const std::regex& reg = std::regex("(.*)"), bool is_recursive = false) { auto p = std::filesystem::path(path); if (!std::filesystem::exists(p.string())) { return {}; }
std::vector<std::string> vec; auto f = [&](const auto& dir_entry) { auto fp = dir_entry.path(); if (!std::filesystem::is_directory(std::filesystem::status(fp))) { auto file_name = fp.filename().string(); if (std::regex_match(file_name, reg)) { vec.push_back(fp.string()); } } };
if (is_recursive) { std::ranges::for_each(std::filesystem::recursive_directory_iterator{p}, f); } else { std::ranges::for_each(std::filesystem::directory_iterator{p}, f); }
std::ranges::sort(vec); return vec; }
int main() {
auto c0 = get_directory_files(dir1.string()); auto c1 = get_directory_files(dir1.string(), std::regex("(.*)"), false); auto c2 = get_directory_files(dir1.string(), std::regex("(.*\\.log)"), false); auto c3 = get_directory_files(dir1.string(), std::regex("(.*)"), true); auto c4 = get_directory_files(dir1.string(), std::regex("(.*\\.log)"), true);
return 0;
}
|
文件重命名
1 2 3 4 5 6 7 8 9 10
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p("hosts"); std::filesystem::path new_p("hosts_new"); std::filesystem::rename(p, new_p); return 0; }
|
移动文件
1 2 3 4 5 6 7 8 9 10
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p("hosts_new_copy"); std::filesystem::path new_p("hosts_new_copy_move"); std::filesystem::rename(p, new_p); return 0; }
|
拷贝文件
1 2 3 4 5 6 7 8 9 10
| #include <iostream> #include <filesystem>
int main() { std::filesystem::path p("hosts_new"); std::filesystem::path new_p("hosts_new_copy"); std::filesystem::copy(p, new_p); return 0; }
|
拷贝文件夹
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| bool copy_directory(const std::string& from, const std::string& to) noexcept { if (!std::filesystem::is_directory(from)) { return false; }
if (!std::filesystem::exists(from)) { return false; }
if (std::filesystem::exists(to)) { return false; } const auto copy_options = std::filesystem::copy_options::update_existing | std::filesystem::copy_options::recursive;
std::error_code code; std::filesystem::copy(from, to, copy_options, code); return !code; }
|