C++/STL/filesystem
外观
< C++
std::filesystem文件系统库提供了文件系统、路径、常规文件、目录等等相关组件进行操作的相关功能。
几个基本类:
- path: 表示路径
- directory_entry:目录条目
- space_info:关于文件系统上空闲及可用空间的信息
- directory_iterator:对目录做迭代访问
- recursive_directory_iterator:对目录几子目录迭代访问
path类
[编辑]#include <iostream>
#include <filesystem>
#include <string>
namespace fs = std::filesystem;
void path_use()
{
fs::path currentPath = fs::current_path();
//获取makefile路径 append operator/ 添加元素到带目录分隔符的路径
fs::path makefilePath = currentPath / "ConsoleApplication1.vcxproj";
std::cout << "Project file path = " << makefilePath.string() << std::endl;
//分解操作
//root_name 返回路径的根名
std::cout << "root_name = " << currentPath.root_name() << std::endl;
//root_directory 返回路径的根目录
std::cout << "root_directory = " << currentPath.root_directory() << std::endl;
//root_path 返回路径的根路径
std::cout << "root_path = " << currentPath.root_path() << std::endl;
//relative_path 返回相对根路径的路径
std::cout << "relative_path = " << currentPath.relative_path() << std::endl;
//parent_path 返回亲路径的路径
std::cout << "parent_path = " << currentPath.parent_path() << std::endl;
//filename 返回文件名路径组分
std::cout << "filename = " << currentPath.filename() << std::endl;
//stem 返回主干路径组分
std::cout << "stem = " << currentPath.stem() << std::endl;
//extension 返回文件扩展名路径组分
std::cout << "extension = " << currentPath.extension() << std::endl;
std::cout << "extension = " << makefilePath.extension() << std::endl;
//查询操作
//empty 检查路径是否为空
std::cout << "empty = " << currentPath.empty() << std::endl;
//检查对应路径元素是否非空
std::cout << "has_root_path = " << currentPath.has_root_path() << std::endl;
std::cout << "has_root_name = " << currentPath.has_root_name() << std::endl;
std::cout << "has_root_directory = " << currentPath.has_root_directory() << std::endl;
std::cout << "has_relative_path = " << currentPath.has_relative_path() << std::endl;
std::cout << "has_parent_path = " << currentPath.has_parent_path() << std::endl;
std::cout << "has_filename = " << currentPath.has_filename() << std::endl;
std::cout << "has_stem = " << currentPath.has_stem() << std::endl;
std::cout << "has_extension = " << currentPath.has_extension() << std::endl;
//检查 root_path() 是否唯一标识文件系统位置
std::cout << "is_absolute = " << currentPath.is_absolute() << std::endl;
std::cout << "is_relative = " << currentPath.is_relative() << std::endl;
}
int main()
{
path_use();
std::cout << std::endl;
return 0;
}
/*输出为:
Project file path = D:\MyPrograms\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.vcxproj
root_name = "D:"
root_directory = "\\"
root_path = "D:\\"
relative_path = "MyPrograms\\ConsoleApplication1\\ConsoleApplication1"
parent_path = "D:\\MyPrograms\\ConsoleApplication1"
filename = "ConsoleApplication1"
stem = "ConsoleApplication1"
extension = ""
extension = ".vcxproj"
empty = 0
has_root_path = 1
has_root_name = 1
has_root_directory = 1
has_relative_path = 1
has_parent_path = 1
has_filename = 1
has_stem = 1
has_extension = 0
is_absolute = 1
is_relative = 0
*/
directory_entry
[编辑]void directory_entry_use()
{
//path operator const path& 返回该目录项代表的路径
fs::path currentPath = fs::current_path();
//获取makefile路径 append operator/ 添加元素到带目录分隔符的路径
fs::path makefilePath = currentPath / "ConsoleApplication1.vcxproj";
std::cout << "Project file path = " << makefilePath.string() << std::endl;
fs::directory_entry dirEntry(currentPath);
//exists 检查 directory_entry 是否代表既存文件系统对象
std::cout << "exists = " << dirEntry.exists() << std::endl;
//is_block_file 检查 directory_entry 是否代表阻塞设备
std::cout << "is_block_file = " << dirEntry.is_block_file() << std::endl;
//is_character_file 检查 directory_entry 是否代表字符设备
std::cout << "is_character_file = " << dirEntry.is_character_file() << std::endl;
//is_directory 检查 directory_entry 是否代表目录
std::cout << "is_directory = " << dirEntry.is_directory() << std::endl;
//is_fifo 检查 directory_entry 是否代表具名管道
std::cout << "is_fifo = " << dirEntry.is_fifo() << std::endl;
//is_other 检查 directory_entry 是否代表其他文件
std::cout << "is_other = " << dirEntry.is_other() << std::endl;
//is_regular_file 检查 directory_entry 是否代表常规文件
std::cout << "is_regular_file = " << dirEntry.is_regular_file() << std::endl;
//is_socket 检查 directory_entry 是否代表具名 IPC 接头
std::cout << "is_socket = " << dirEntry.is_socket() << std::endl;
//is_symlink 检查 directory_entry 是否代表符号链接
std::cout << "is_symlink = " << dirEntry.is_symlink() << std::endl;
//file_size 返回 directory_entry 所指代的文件大小
std::cout << "file_size = " << dirEntry.file_size() << std::endl;
//hard_link_count 返回引用到该 directory_entry 所表示的文件的硬链接数
std::cout << "hard_link_count = " << dirEntry.hard_link_count() << std::endl;
}
int main()
{
directory_entry_use();
return 0;
}
/*输出为:
Project file path = D:\MyPrograms\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.vcxproj
exists = 1
is_block_file = 0
is_character_file = 0
is_directory = 1
is_fifo = 0
is_other = 0
is_regular_file = 0
is_socket = 0
is_symlink = 0
file_size = 4096
hard_link_count = 1
*/
space_info
[编辑]void space_info_use()
{
//capacity文件系统的总大小,以字节计
//free文件系统的空闲空间,以字节计
//available非特权进程可用的空闲空间(可以小于或等于 free )
fs::path currentPath = fs::current_path();
std::cout << "Current path is " << fs::current_path() << std::endl;
fs::path parentPath = currentPath.parent_path();
std::cout << "Parent path is " << parentPath.string() << std::endl;
fs::space_info devi = fs::space(currentPath);
fs::space_info tmpi = fs::space(parentPath);
std::cout << ". Capacity Free Available\n"
<< "current path: " << devi.capacity << " "
<< devi.free << " " << devi.available << '\n'
<< "parent path: " << tmpi.capacity << " "
<< tmpi.free << " " << tmpi.available << '\n';
}
int main()
{
space_info_use();
return 0;
}
/*输出为:
Current path is "D:\\MyPrograms\\ConsoleApplication1\\ConsoleApplication1"
Parent path is D:\MyPrograms\ConsoleApplication1
. Capacity Free Available
current path: 668955832320 442984341504 442984341504
parent path: 668955832320 442984341504 442984341504
*/
目录迭代
[编辑]#include <fstream>
#include <iostream>
#include <filesystem>
#include <algorithm>
int main()
{
const std::filesystem::path sandbox{"sandbox"};
std::filesystem::create_directories(sandbox/"dir1"/"dir2");
std::ofstream{sandbox/"file1.txt"};
std::ofstream{sandbox/"file2.txt"};
std::cout << "directory_iterator:\n";
// directory_iterator can be iterated using a range-for loop
for (auto const& dir_entry : std::filesystem::directory_iterator{sandbox})
{
std::cout << dir_entry << '\n';
}
std::cout << "\ndirectory_iterator as a range:\n";
// directory_iterator behaves as a range in other ways, too
std::ranges::for_each( std::filesystem::directory_iterator{sandbox},
[](const auto& dir_entry) {
std::cout << dir_entry << '\n';
} );
std::cout << "\nrecursive_directory_iterator:\n";
for (auto const& dir_entry : std::filesystem::recursive_directory_iterator{sandbox})
{
std::cout << dir_entry << '\n';
}
// delete the sandbox dir and all contents within it, including subdirs
std::filesystem::remove_all(sandbox);
}
/*
Possible output:
directory_iterator:
"sandbox/file2.txt"
"sandbox/file1.txt"
"sandbox/dir1"
directory_iterator as a range:
"sandbox/file2.txt"
"sandbox/file1.txt"
"sandbox/dir1"
recursive_directory_iterator:
"sandbox/file2.txt"
"sandbox/file1.txt"
"sandbox/dir1"
"sandbox/dir1/dir2"
*/