绿色学校网站模板seo顾问赚钱吗
filesystem的内容比较多,前面给你列出整个文件系统的构成,使你有个大概的框架。由于内容太多,不可能用一篇文章讲述完。在这里我重点讲述一些常见操做。
要学会使用path类,directory_iterator迭代类,基本函数的操作
1)path类具体包括文件路径的合并于拆分,连接,当前目录获取
2)directory_iterator迭代类主要用于目录的循环迭代。
3)基本公共函数操作包括文件目录存在判断,文件权限操作,文件及文件夹的拷贝,更名,删除等操作;简单的文本写入。
序言:类结构:
filesystem Classes: path 表示路径 filesystem_error 文件系统错误引发的异常 directory_entry 目录条目 directory_iterator 目录内容的迭代器 recursive_directory_iterator 目录及其子目录(类)的迭代器file_status 表示文件类型和权限 space_info 有关文件系统上可用空间和可用空间的信息 file_type 文件类型(枚举)perms 标识文件系统权限(枚举)perm_options 指定权限操作的语义(枚举)copy_options 指定复制操作的语义(枚举)directory_options 迭代目录内容的选项(枚举)file_time_type 代表文件时间值(typedef)
第一部分:path操作
成员函数:
1.class: path() noexcept; //构造函数:path& assign(string_type&& source); // 分配内容 path& assign(const Source& source); path& assign(InputIt first,InputIt last); path& operator/=(const path& p); // 路径附加path& operator/= (constSource& source); path& append(const Source& source); path& append(InputIt first,InputIt last); //路径连接- 在不引入目录分隔符的情况下串联两个路径path& operator+=(const path& x); path& operator+=(const string_type& x); path& operator+=(basic_string_view<value_type> x); path& operator+=(const value_type* x); path& operator+=(value_type x); path& operator+=(const Source& x); path& operator+=(ECharT x); path& concat(const Source& x); path& concat(InputIt first,InputIt last); // 转换为本机格式 const string_type& native() const noexcept; const value_type* c_str() const noexcept; operator string_type() const; std::string string()const; 路径转换为字符串 //路径操作:void clear() noexcept; 删除内容path& make_preferred(); 将目录分隔符转换为首选目录分隔符path& remove_filename(); 删除文件名 path& replace_filename(const path& replacement); 路径替换 path& replace_extension(const path& replacement = path()); 替换扩展名 void swap(path& rhs) noexcept; 交换两个路径 //路径比较int compare(const path& p) const noexcept; int compare(const string_type& s) const; int compare(basic_string_view<value_type> s) const; int compare(const value_type*s) const;
//路径属性:
path root_name() const;
用途:返回根名称(如果存在)
说明:如paths中无根目录则返回空 path root_directory() const;
用途:返回根目录分隔符(如果存在)
说明:返回根目录分隔符-如有根目录(含分隔符)返回分隔符如有根目录(不含分隔符)返回空如无根目录文件夹最前有分隔符则返回该分隔符,如无则返回空path root_path() const;
用途:返回根目录(如果存在)
说明:如paths中无根目录无前分隔符则返回空如paths中无根目录有前分隔符则返回原样前分隔符如有根目录则原样输出根目录(非标准形式D:log.exe也可输出)path relative_path() const;
用途:返回相对于根路径的路径
说明:如有根目录(支持非标准形式)返回根目录分隔符后的内容,首不含分隔符如无根目录则原样输出(但去除首分割符)path parent_path() const;
用途:返回上级目录 支持非标准形式如D:log.exe结果尾部无分隔符
说明:有无根目录前面原样输出,如尾部是分隔符则删除分隔符如尾部是文件或文件夹则删除path filename() const;
用途:返回文件名-含后缀
说明:如路径中有文件名则返回如路径中无文件名如无尾分隔符则返回最后的文件夹名如路径中无文件名有尾分隔符则返回空path stem() const;
用途:返回文件名-不含后缀支持非标准形式
说明:如无文件名无后缀分隔符则返回最后的文件夹名如无文件名有后缀分隔符则返回空path extension() const;
用途:返回文件扩展名 -支持非标准形式说明:如无文件名返回空 //路径检测:bool empty() const noexcept; 检查路径是否为空 bool has_root_name() const; bool has_root_directory() const; 检查是否有根目录分隔符 bool has_root_path() const; bool has_relative_path() const; bool has_parent_path() const; bool has_filename() const; bool has_stem() const; boolhas_extension() const; bool is_absolute() const; boolis_relative() const; //路径转换:path lexically_normal() const; 将路径转换为普通形式path lexically_relative(const path& base) const; 将路径转换为相对形式path lexically_proximate(const path& base)const; 将路径转换为近似形式 iterator begin() const; iteratorend() const; operator<<,operator>> 在路径上执行流输入和输出
path实例:
#include <iostream>
#include <string>
#include<vector>
#include<filesystem>
#include<cassert> //using namespace std;
namespace fs = std::filesystem;
using std::string; //path文件名测试:不用考虑当前目录,不用考虑文件是否真实存在
//注意:这些函数有很多注意事项,使用时要特别注意
//说明:分隔符为"\\"或"/"等效;建议用"\\"void test_path_rootpath(fs::path paths = "D:/A/B/C/tmp.txt") {using namespace std; cout << paths.root_name() << endl; //"D:" //说明:如何paths中无根目录则返回空cout << paths.root_path() << endl; //"D:/" //说明://如何paths中无根目录无前分隔符则返回空//如何paths中无根目录有前分隔符则返回原样前分隔符//如有根目录则原样输出根目录(非标准形式D:log.exe也可输出)cout << paths.root_directory() << endl; //"/"//返回根目录分隔符-如有根目录(含分隔符)返回分隔符//如有根目录(不含分隔符)返回空//如无根目录文件夹最前有分隔符则返回该分隔符,如无则返回空cout << paths.relative_path() << endl; //"A\\B\\C\\tmp.txt"//说明://如有根目录(支持非标准形式)返回根目录分隔符后的内容,首不含分隔符//如无根目录则原样输出(但去除首分割符)cout << paths.parent_path() << endl; //"D:/A/B/C"//返回上级目录:支持非标准形式如D:log.exe结果尾部无分隔符//有无根目录前面原样输出,如尾部是分隔符则删除分隔符//如尾部是文件或文件夹则删除cout << paths.filename() << endl; //"tmp.txt"//返回文件全名:如路径中有文件名则返回//如路径中无文件名如无尾分隔符则返回最后的文件夹名//如路径中无文件名有尾分隔符则返回空cout << paths.stem() << endl; //"tmp"//仅仅返回文件名-不含后缀支持非标准形式//如无文件名无后缀分隔符则返回最后的文件夹名//如无文件名有后缀分隔符则返回空cout << paths.extension() << endl; //".txt"//返回文件后缀名-支持非标准形式;如无文件名返回空
}
//path基本操作:不用考虑当前目录,不用考虑文件是否真实存在
void test_path() {using namespace std;//1.构造路径://fs::path paths("D:/A/B/C/tmp.txt");//fs::path paths{ "D:/A/B/C/tmp.txt" };fs::path paths = "D:/A/B/C/tmp.txt"; //2.路径重新分配: 注意1paths.assign("D:\\");//3.路径附加:paths = paths / "A" / "B" / "C" / "tmp.txt"; //"D:\\A\\B\\C\\tmp.txt"cout << "paths= " << paths << endl; paths.assign("D:\\");paths.append("A").append("B").append("C").append("tmp.txt");cout << "paths= " << paths << endl; //"D:\\A\\B\\C\\tmp.txt" //4.路径连接:paths.assign("D:/");paths += "A/B/C/tmp.txt"; //"D:/A/B/C/tmp.txt" cout << "paths= " << paths << endl; paths.assign("D:/");paths.concat("A/B/C/tmp.txt"); //"D:/A/B/C/tmp.txt"cout << "paths= " << paths << endl; //5.path转换const std::wstring ws = paths.native();const wchar_t* pwc = paths.c_str();const std::string s= paths.string(); //6.filename操作:assert(paths.has_filename() == true);paths.remove_filename(); //删除文件名assert(paths.has_filename() == false); paths += "tmp.txt";paths.replace_filename("girl.jpg"); //替换文件名cout << paths << endl;//"D:/A/B/C/girl.jpg"paths.replace_extension("log"); //替换文件扩展名cout << paths << endl;//"D:/A/B/C/girl.log"//7.路径转换assert(fs::path("foo/./bar/..").lexically_normal() == "foo/");assert(fs::path("foo/.///bar/../").lexically_normal() == "foo/"); assert(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d");assert(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c");assert(fs::path("a/b/c").lexically_relative("a") == "b/c");assert(fs::path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");assert(fs::path("a/b/c").lexically_relative("a/b/c") == ".");assert(fs::path("a/b").lexically_relative("c/d") == "../../a/b"); //8.迭代:for (auto v : paths) cout << v << ",";cout << '\n'; //"D:","/","A","B","C","girl.log", for (auto it = paths.begin(); it != paths.end(); ++it)cout << *it << ',';cout << endl; //"D:","/","A","B","C","girl.log",
}
//好多操作和当前目录有关,建议先设置当前目录
int main() {using std::cout;using std::endl; fs::current_path("C:\\Users"); //设置当前路径fs::path cur_path = fs::current_path();assert(cur_path.compare("C:\\Users") == 0); test_path_rootpath();test_path();
}
注意1:连接首个不插入分隔符,第二个插入分隔符:
path path1,path2;path1.assign("C:");path1 /= "Users"; // 不插入分隔符path1 /= "source"; // 插入分隔符std::cout << path1 << '\n'; //"C:Users\\source"path2.assign("C:\\");path2 /= "Users"; path2 /= "source\\tmp.txt"; cout << path2 << '\n'; //"C:\\Users\\source\\tmp.txt"auto path3 = path2.parent_path();path3 += "_Tmp.txt"; //"C:\\Users\\source_Tmp.txt"
第二部分:迭代:
1.1.常用类: class path : 主要用于路径及文件名的操作。如提取合并 class directory_entry : 文件入口主要用于获取文件信息 class directory_iterator :用于目录路径目录的迭代,元素为directory_entry对象 class file_status : 表示文件类型和权限 1.2.使用: 1)创建path对象,如需修改路径可调用其成员函数 2)要获取文件信息需通过path构造directory_entry,但path一定存在无则抛异常 调用exists(path)确保目录存在;directory_entry.exists()只能在创建后判断 3)用 directory_iterator进行遍历
2.实例: #include <iostream> #include <string> #include<vector> #include<filesystem> namespace fs = std::filesystem;using std::cout; using std::endl;//仅仅迭代当前目录下所有文件及文件夹 std::vector<std::string> viewPath(const std::string &dir) {std::vector<std::string> rst{};if (!fs::exists(dir)) return rst;for (auto& it : fs::directory_iterator(dir)) {std::string tmp = it.path().string();rst.push_back(tmp);}return rst;}
//递归所有文件及文件夹 std::vector<std::string> recursivePath(const std::string &dir, const std::string& rootpath, const std::string& iterpath) {std::vector<std::string> rst{};if (!fs::exists(dir)) return rst;fs::path old_curpath = fs::current_path();fs::current_path(rootpath);for (auto& it : fs::recursive_directory_iterator(iterpath)) {std::string tmp = it.path().string();rst.push_back(tmp);}fs::current_path(old_curpath);return rst;}
int main() { std::string str{ "C:\\Users\\Default\\AppData\\Local\\Microsoft" };std::string rootpath = "C:\\Users\\Default\\AppData\\Local";std::string iterpath = "Microsoft";std::vector<std::string> str_vec;fs::path paths(str);//递归显示Local文件夹下所有内容 str_vec= recursivePath(str, rootpath, iterpath); for (auto v : str_vec) cout << v << endl; cout << endl; //仅仅显示Microsoft文件夹中的内容 str_vec = viewPath(str); for (auto v : str_vec) cout << v << endl; cout << endl; //迭代指定目录下的目录:不递归 if (!fs::exists(paths)) return 1; //先检测目录是否存在才能使用文件入口. fs::directory_entry entry(paths); //文件入口 if (entry.status().type() == fs::file_type::directory) cout << "该路径是一个目录" << endl; fs::directory_iterator dire_iter(paths); //文件入口容器 for (auto& it : dire_iter) { //通过文件入口it获取path对象,再得到path对象文件名 if(fs::is_directory(it.path())) cout<<"目录=";else cout<<"文件";cout << absolute(it.path()) << endl; } }
第三部分:公共函数操作:
常用库函数:
path absolute(const path& p, [error_code& ec]);
用途:获取绝对路径
说明:将path转为绝对路径;同时会修改为标准路径如D:log.exe被修改为D:\\log.exe 如路径无根目录则将当前目录添加到前面,其他保持不变;/等效\\ path relative(const path& p, error_code& ec);
path relative(const path& p, const path& base = current_path());
path relative(const path& p, const path& base, error_code& ec);
用途:获取相对路径
说明:将path转为相对于当前目录的路径;路径不规范,前缀无"\\" or"/"输出空,根目录不同都输出空 删除尾部"\\" or"/"符号 path canonical(const path& p, [error_code& ec]);
用途: 组成规范路径
说明:将存在的path转为绝对路径;路径不规范可修改 前缀有无分隔符都可,有前缀的只能是文件夹("/A/B/C/tmp.txt"将报错)无前缀的文件夹文件都可 删除尾部"\\" or"/"符号 path weakly_canonical(const path& p, [error_code& ec]);
说明:返回由operator/=调用结果组成的路径该调用结果包含canonical()由存在的前导元素组成的path参数p
//组成相对路径
path proximate(const path& p, error_code& ec);
path proximate(const path& p, const path& base = current_path());
path proximate(const path& p, const path& base, error_code& ec); //复制文件或目录
void copy(const path& from, const path& to,[copy_options options, error_code& ec]); //复制文件内容
bool copy_file(const path& from, const path& to,[copy_options option,error_code& ec]); //复制符号链接
void copy_symlink(const path& existing_symlink, const path& new_symlink, [error_code& ec]) ; //当目录不存在时创建目录
bool create_directory(const path& p, [error_code& ec]) noexcept;
bool create_directory(const path& p, const path& attributes, [error_code& ec]) noexcept; //创建目录结构
bool create_directories(const path& p, [error_code& ec]); //创建硬链接
void create_hard_link(const path& to, const path& new_hard_link, [error_code& ec]) noexcept; //创建一个符号链接
void create_symlink(const path& to, const path& new_symlink, [error_code& ec]) noexcept;
void create_directory_symlink(const path& to, const path& new_symlink, [error_code& ec]) noexcept; //返回或设置当前工作目录
path current_path([error_code& ec]);
void current_path(const path& p, [error_code& ec]) noexcept; //判断path是否存在
bool exists(file_status s) noexcept;
bool exists(const path& p, [error_code& ec]) noexcept; //检查两个路径是否引用相同的文件系统对象
bool equivalent(const path& p1, const path& p2, [error_code& ec]) noexcept; //返回引用特定文件(功能)的硬链接数
uintmax_t hard_link_count(const path& p, [error_code& ec]) noexcept; //获取或设置上次数据修改的时间
file_time_type last_write_time(const path& p, [error_code& ec]) noexcept;
void last_write_time(const path& p, file_time_type new_time, [error_code& ec]) noexcept; //修改文件访问权限
void permissions(const path& p, perms prms, perm_options opts=perm_options::replace);
void permissions(const path& p, perms prms, [perm_options opts], error_code& ec); //获取符号链接(功能)的目标
path read_symlink(const path& p, [error_code& ec]); //删除目录
bool remove(const path& p, [error_code& ec]) noexcept; //递归删除文件或目录 或空目录
uintmax_t remove_all(const path& p, [error_code& ec]); //移动或重命名文件或目录
void rename(const path& from, const path& to, [error_code& ec]) noexcept; //通过截断或零填充更改常规文件的大小
void resize_file(const path& p, uintmax_t size, [error_code& ec]) noexcept; //确定文件系统上的可用空间
space_info space(const path& p, [error_code& ec]) noexcept; //确定文件属性,检查符号链接目标
file_status symlink_status(const path& p, [error_code& ec]) noexcept; //返回适合临时文件的目录
path temp_directory_path([error_code& ec]); //返回文件的大小
uintmax_t file_size(const path& p, [error_code& ec]) noexcept;
file_status status(const path& p, [error_code& ec]) noexcept;
File types文件类型 //检查给定路径是否指向块设备 bool is_block_file(file_status s) noexcept; bool is_block_file(const path& p, [error_code& ec]) noexcept; //检查给定的路径是否指向字符设备 bool is_character_file(file_status s) noexcept; bool is_character_file(const path& p, [error_code& ec]) noexcept; //检查给定的路径是否引用目录 bool is_directory(file_status s) noexcept; bool is_directory(const path& p, [error_code& ec]) noexcept; //检查给定的路径是否指向空文件或目录 bool is_empty(const path& p, [error_code& ec]); //检查给定路径是否引用命名管道 bool is_fifo(file_status s) noexcept; bool is_fifo(const path& p, [error_code& ec]) noexcept; //检查参数是否引用其他文件 bool is_other(file_status s) noexcept; bool is_other(const path& p, [error_code& ec]) noexcept; //检查参数是否引用常规文件 bool is_regular_file(file_status s) noexcept; bool is_regular_file(const path& p,[ error_code& ec]) noexcept; //检查参数是否引用命名的IPC套接字 bool is_socket(file_status s) noexcept; bool is_socket(const path& p, [error_code& ec]) noexcept; //检查参数是否引用符号链接 bool is_symlink(file_status s) noexcept; bool is_symlink(const path& p, [error_code& ec]) noexcept; //检查文件状态是否已知bool status_known(file_status s) noexcept;
公共函数实例:
#include <iostream> #include <string> #include<filesystem> #include <fstream> #include<cassert> #include <bitset> namespace fs = std::filesystem;using std::string;using std::cout; using std::endl;//基本函数测试: //注意:许多函数考虑当前目录,考虑文件是否真实存在 //说明:分隔符为"\\"或"/"等效;建议用"\\"
//1.基本函数测试:测试绝对相对路径
void test_base_function_absolute(fs::path paths = "D:/A/B/C/tmp.txt") {//1.1.绝对路径: //将path转为绝对路径;同时会修改为标准路径如D:log.exe被修改为D:\\log.exe //如路径无根目录则将当前目录添加到前面,其他保持不变;/等效\\ fs::path abs_path = fs::absolute(paths);assert(fs::absolute(abs_path).compare(paths) == 0);//1.2.相对路径: //将path转为相对于当前目录的路径;路径不规范,前缀无"\\" or"/"输出空,根目录不同都输出空 //删除尾部"\\" or"/"符号 fs::path rel_path = fs::relative("../A/B/C/tmp.txt");cout <<"rel_path = "<< fs::relative(rel_path) << endl;//可能的输出:"..\\A\\B\\C\\tmp.txt"//1.3.实际存在的路径转换为规范的绝对路径: //将存在的path转为绝对路径;路径不规范可修改 //前缀有无分隔符都可,有前缀的只能是文件夹("/A/B/C/tmp.txt"将报错)无前缀的文件夹文件都可 //删除尾部"\\" or"/"符号 if (!fs::exists(paths)) {fs::create_directories("D:/A/B/C");std::ofstream("D:/A/B/C/tmp.txt").write("1.My name is Tom.\n2.I come from China.", 38);}fs::path exist_abs_path = fs::canonical("D:/A/B/C/tmp.txt");assert(fs::canonical(exist_abs_path).compare("D:\\A\\B\\C\\tmp.txt") == 0);//1.4.weakly_canonical //返回由operator/=调用结果组成的路径,该调用结果包含canonical()由存在的前导元素组成的path参数p fs::path exist_abs_weakly_path = fs::weakly_canonical("D:/A/B/C") / "tmp.txt";assert(fs::weakly_canonical(exist_abs_weakly_path).compare("D:\\A\\B\\C\\tmp.txt") == 0);fs::current_path("C:\\Windows");fs::path p = fs::path(".") / "Boot";//.当前目录fs::path p1 = fs::path("..") /"Windows" / "Boot";//..当前目录的上级目录cout << "Current path is " << fs::current_path() << '\n';cout << "Canonical path for " << p << " is " << fs::canonical(p) << '\n';cout << "Canonical path for " << p1 << " is " << fs::canonical(p1) << '\n';
}
//2.基本函数测试:文件及文件夹操作权限查看
std::string _get_Perms(fs::perms p)//查看路径权限
{string rst;rst = rst + ((p & fs::perms::owner_read) != fs::perms::none ? "r" : "-");rst = rst + ((p & fs::perms::owner_write) != fs::perms::none ? "w" : "-");rst = rst + ((p & fs::perms::owner_exec) != fs::perms::none ? "x" : "-");rst = rst + ((p & fs::perms::group_read) != fs::perms::none ? "r" : "-");rst = rst + ((p & fs::perms::group_write) != fs::perms::none ? "w" : "-");rst = rst + ((p & fs::perms::group_exec) != fs::perms::none ? "x" : "-");rst = rst + ((p & fs::perms::others_read) != fs::perms::none ? "r" : "-");rst = rst + ((p & fs::perms::others_write) != fs::perms::none ? "w" : "-");rst = rst + ((p & fs::perms::others_exec) != fs::perms::none ? "x" : "-");return rst;
}std::string get_Perms(std::string dir)
{return _get_Perms(fs::status(dir).permissions());
}
//基本函数测试:测试路径权限
void test_Perms() {std::string dirs{ "D:/A/B/C/D1" };fs::create_directories(dirs);//查看路径权限: cout << "path perms=" << get_Perms(dirs) << endl;//设置路径权限: fs::permissions(dirs, fs::perms::owner_all | fs::perms::group_all,fs::perm_options::add);cout << "path perms==" << get_Perms(dirs) << endl;fs::permissions(dirs, fs::perms::group_all, fs::perm_options::remove);cout << "path perms==" << get_Perms(dirs) << endl;//查看路径权限: dirs = "D:/A/B/C/D1/test.txt";std::ofstream(dirs.c_str());cout << "file perms=" << get_Perms(dirs) << endl;//设置路径权限: fs::permissions(dirs, fs::perms::owner_all | fs::perms::group_all,fs::perm_options::add);cout << "file perms=" << get_Perms(dirs) << endl;fs::permissions(dirs, fs::perms::group_all, fs::perm_options::remove);cout << "file perms=" << get_Perms(dirs) << endl;fs::remove_all("D:/A");
}
//3.基本函数测试:创建目录
void test_create_directory() {//设置当前目录: cout << fs::current_path() << endl;fs::current_path("D:\\"); //fs::temp_directory_path() //创建目录: //根目录根据需要可在路径中也可不用。文件夹存在不报错 //路径名中间不允许有空格 fs::create_directories("A/B/C/D1");fs::create_directory("A/B/C/D2");//D2的上级目录必须存在 fs::create_directory(fs::path("A/B") / "C1");//显示当前目录文件夹结构: //static_cast<void>(std::system("tree")); std::system("cd A/B");std::system("tree A ");fs::create_directories("D:/A1/B1/C1/D1");fs::create_directory("D:/A1/B1/C1/D2"); //D2的上级目录必须存在 fs::create_directories("D:/A2/B2/C2/D1");fs::create_directory("D:/A2/B2/C2/D2"); //D2的上级目录必须存在 //设置路径读写权限: fs::permissions("A/B/C/D2", fs::perms::others_all, fs::perm_options::remove);fs::create_directory("A/B/C/D3", "A/B/C/D2");fs::remove_all("D:\\A");fs::remove_all("D:\\A1");fs::remove_all("D:\\A2");
}
/*
D:\A
└─B├─C│ ├─D1│ └─D2└─C1
*/
//4.基本函数测试:copy
void test_copy() {fs::current_path("D:\\"); //设置当前目录 fs::create_directories("Fastener/Resourse/Picture"); //创建3个子目录 //将数据写入文件:存在不报错,不存在创建 std::ofstream("Fastener/log1.txt").write("1.My name is Tom.\n2.I come from China.", 38);//拷贝文件文件夹:默认存在错误 if (!fs::exists("Fastener/log2.txt"))fs::copy("Fastener/log1.txt", "Fastener/log2.txt"); // copy file 文件夹必须存在fs::copy("Fastener/Resourse", "Fastener/dir2"); //复制目录(非递归))文件夹必须存在 //拷贝文件或文件夹: const auto copyOptions = fs::copy_options::update_existing| fs::copy_options::recursive //递归| fs::copy_options::directories_only //只有目录-去掉本句下面拷贝所有;fs::copy("Fastener", "FastenerCopy", copyOptions);//显示当前目录文件夹结构: fs::current_path("D:/Fastener");static_cast<void>(std::system("tree"));//删除所有文件夹及文件 fs::remove_all("Fastener"); //不存在不报错 fs::remove_all("FastenerCopy");
}
//5.基本函数测试:rename移动或重命名
void test_rename() {fs::current_path("D:\\");fs::path paths = fs::current_path() / "Run"; //"D:\\Run" assert(paths.compare("D:\\Run") == 0);fs::create_directories(paths / "from"); //创建目录存在不报错 fs::create_directory(paths / "to"); //创建目录std::ofstream(paths / "from/boy.txt").put('a'); //创建文件:存在重写//将from文件夹下的文件更名并移到to文件夹下: //fs::rename(paths/"from/boy.txt", paths/"to/"); // error: to is a directory if (!fs::is_empty(paths / "from/") && !fs::is_empty(paths / "to"))fs::rename(paths / "from/boy.txt", paths / "to/girl.txt");//将from文件夹更名并移到to文件夹下 //fs::rename(paths/"from", paths/"to"); // error: to is not empty fs::rename(paths / "from", paths / "to/RunSubdir");//删除Run文件下的所有内容: fs::remove_all(paths);
}bool isExists(const fs::path& p, fs::file_status s = fs::file_status{})
{return (fs::status_known(s) ? fs::exists(s) : fs::exists(p));
}
//6.基本函数测试:存在判断
void test_exists() {try {//必须有客户端权限fs::create_directory("sandbox");fs::permissions("sandbox", fs::perms::all, fs::perm_options::add);std::ofstream("sandbox/file"); // 创建常规文件 fs::create_symlink("non-existing", "sandbox/symlink");cout << "sandbox=" << isExists("sandbox") << endl;for (auto it = fs::directory_iterator("sandbox"); it != fs::directory_iterator(); ++it)cout << it->path().string() << "=" << isExists(*it, it->status()) << endl; // use cached status from directory entryfs::remove_all("sandbox");}catch (fs::filesystem_error&e) { cout << e.what() << endl; }
}/*
sandbox=1
sandbox\file=1
sandbox\symlink=0
*/
int main() {fs::current_path("C:\\Users"); //设置当前路径 fs::path cur_path = fs::current_path();assert(cur_path.compare("C:\\Users") == 0);test_base_function_absolute();test_Perms(); //测试文件权限 test_create_directory(); //创建文件夹测试 test_copy(); //测试文件及文件夹拷贝 test_rename(); //测试更名和移动 test_exists(); //存在判断
}
4.other
#include <iostream>
#include <filesystem>
#include <fstream>
#include <string>using namespace std;
void view_path(string str) {using namespace std::filesystem;path Resourse;Resourse.assign(str);cout << "根名称=" << Resourse.root_name() << endl; //"C:"cout << "根目录=" << Resourse.root_path() << endl; //"C:\\"cout << "相对路径=" << Resourse.relative_path() << endl;//"Users\\source\\repos\\tmp.txt"cout << "绝对路径=" << Resourse.parent_path() << endl; //"C:\\Users\\source\\repos"cout << "全文件名=" << Resourse.filename() << endl; //"tmp.txt"cout << "仅文件名=" << Resourse.stem() << endl; //"tmp"cout << "文件后缀=" << Resourse.extension() << endl; //".txt"cout << endl;
}void test_path() {string str;str = "C:\\Users\\source\\repos\\tmp.txt"; view_path(str);str = "C:\\Users\\source\\repos"; view_path(str);str = "\\Users\\source\\repos\\"; view_path(str);str = "Users\\source\\repos\\"; view_path(str);str = "C:/Users/source/repos/tmp.txt"; view_path(str);str = "C:/Users/source/repos"; view_path(str);str = "/Users/source/repos/"; view_path(str);str = "Users/source/repos/"; view_path(str);
}
看到吧,有很多注意事项,不直观,为方便应用,做个简单的封装吧。
class Path {
private:using path = std::filesystem::path;using string = std::string;path Resourse;public:void assign(string str) { Resourse.assign(str); }void assign(const char* str) { Resourse.assign(str); }void assign(path str) { Resourse.assign(str); }path get_RootName() { return Resourse.root_name(); }path get_RootPath(); path get_RelativePath() {return Resourse.relative_path(); }path get_AbsolutePath() {return Resourse;}path get_FileName();path get_PrefixName();path get_SuffixName() {return Resourse.extension();}path operator+(const Path& obj) { this->Resourse.assign(this->Resourse.string() + obj.Resourse.string()); }path operator+(const string& obj) { this->Resourse.assign(this->Resourse.string() + obj); }string to_string(path Resourse) { return Resourse.string(); }
};
std::filesystem::path Path::get_RootPath() {std::filesystem::path rst = Resourse.root_path();std::string str = rst.string();if (str.size() < 1)return rst;if (!isalpha(str[0])) rst.clear();return rst;
}std::filesystem::path Path::get_FileName() {std::filesystem::path rst = Resourse.filename();std::string str = rst.string();if (str.find('.') == str.npos) rst.clear();return rst;
}std::filesystem::path Path::get_PrefixName() {std::filesystem::path rst = Resourse.filename();std::string str = rst.string(); size_t n = str.find('.');if (n == str.npos) rst.clear();else rst.assign(str.substr(0, n));return rst;
}
以下是测试函数:
void view_Path(string str) {Path Resourse;Resourse.assign(str);cout << "根名称=" << Resourse.get_RootName() << endl; //"C:"cout << "根目录=" << Resourse.get_RootPath() << endl; //"C:\\"cout << "相对路径=" << Resourse.get_RelativePath() << endl;//"Users\\source\\repos\\tmp.txt"cout << "绝对路径=" << Resourse.get_AbsolutePath() << endl;//"C:\\Users\\source\\repos"cout << "全文件名=" << Resourse.get_FileName() << endl; //"tmp.txt"cout << "仅文件名=" << Resourse.get_PrefixName() << endl; //"tmp"cout << "文件后缀=" << Resourse.get_SuffixName() << endl; //".txt"cout << endl;
}
void test_Path()
{string str;str = "C:\\Users\\source\\repos\\tmp.txt";view_Path(str);str="C:\\Users\\source\\repos"; view_Path(str);str="\\Users\\source\\repos\\";view_Path(str);str="Users\\source\\repos\\";view_Path(str);str="C:/Users/source/repos/tmp.txt";view_Path(str);str="C:/Users/source/repos";view_Path(str);str="/Users/source/repos/";view_Path(str);str="Users/source/repos/";view_Path(str);
}
int main() {test_Path();
}