filesystem库是一个可移植的文件系统操作库,它在底层做了大量的工作,使用POSIX标准表示文件系统的路径,使C++具有了类似脚本语言的功能,可以跨平台操作目录、文件,写出通用的脚本程序。
1.path的构造函数可以接受C字符串和string,也可以是一个指定首末迭代器字符串序列区间。
2.filesystem提供了一系列的文件名(或目录)检查函数。
3.有丰富的函数用于获取文件名、目录名、判断文件属性等等。
4.filesystem库使用异常来处理文件操作时发生的错误。
5.filesystem库提供一个文件状态类file_status及一组相关函数,用于检查文件的各种属性,如是否存在、是否是目录、是否是符号链接等。
6.filesystem提供了少量的文件属性操作,如windows下的只读、归档等,Linux下的读写权限等。
7.文件操作,如创建目录、文件改名、文件删除、文件拷贝等等。
8.basic_directory_iterator提供了迭代一个目录下所有文件的功能。
一、path类的基本用法
//注意 /= 和 += 的区别, /= 表示追加下级目录, += 仅仅是字符串的串接
path dir("C:\\Windows");
dir /= "System32"; //追加下级目录dir /= "services.exe";
std::cout << dir << std::endl;std::cout << dir.string() << std::endl; //转换成std::string 类型std::cout << dir.root_name()<< std::endl; //盘符名:C:
std::cout << dir.root_directory()<< std::endl; //根目录:"\"
std::cout << dir.root_path()<< std::endl; //根路径:"C:\"
std::cout << dir.relative_path()<< std::endl; // 相对路径:Windows\System32\services.exe
std::cout << dir.parent_path()<< std::endl; //上级目录:C:\Windows\System32
std::cout << dir.filename()<< std::endl; //文件名:services.exe
std::cout << dir.stem()<< std::endl; //不带扩展的文件名:services
std::cout << dir.extension()<< std::endl; //扩展名:.exe
二、常用函数及异常处理
函数名 作用
system_complete(path); 返回完整路径(相对路径+当前路径)
exists(path); 目录是否存在
is_directory(path);
is_directory(file_status); 是否是路径
is_regular_file(path);
is_regular_file(file_status); 是否是普通文件
is_symlink(path);
is_symlink(file_status); 是否是一个链接文件
file_status status(path); 返回路径名对应的状态
initial_path(); 得到程序运行时的系统当前路径
current_path(); 得到系统当前路径
current_path(const Path& p); 改变当前路径
space_info space(const Path& p); 得到指定路径下的空间信息,space_info 有capacity, free 和 available三个成员变量,分别表示容量,剩余空间和可用空间。
last_write_time(const Path& p); 最后修改时间
last_write_time(const Path& p, const std::time_t new_time); 修改最后修改时间
bool create_directory(const Path& dp); 建立路径
create_hard_link(const Path1& to_p, const Path2& from_p);
error_code create_hard_link(const Path1& to_p, const Path2& from_p, error_code& ec); 建立硬链接
create_symlink(const Path1& to_p, const Path2& from_p);
create_symlink(const Path1& to_p, const Path2& from_p, error_code& ec); 建立软链接
remove(const Path& p, system::error_code & ec = singular ); 删除文件
remove_all(const Path& p); 递归删除p中所有内容,返回删除文件的数量
rename(const Path1& from_p, const Path2& to_p); 重命名
copy_file(const Path1& from_fp, const Path2& to_fp); 拷贝文件
omplete(const Path& p, const Path& base=initial_path<Path>()); 以base以基,p作为相对路径,返回其完整路径
create_directories(const Path & p); 建立路径
//常用函数及异常
try
{path dir2("c:\\Windows\\System32");
assert(is_directory(dir2)); //判断是否一个目录
assert(exists(dir2)); //判断目录是否存在
}catch(filesystem_error& e)
{std::cout << e.path1() << std::endl;std::cout << e.what() << std::endl;}
三、目录迭代
boost库提供了两个迭代器
directory_iterator :只支持本层目录遍历
recursive_directory_iterator :支持深度遍历
输出指定目录下的文件:
path dir2("c:\\Windows\\System32");
directory_iterator end;for (directory_iterator pos(dir2); pos != end; pos++)
{std::cout << *pos << std::endl;}
使用深度遍历
typedef recursive_directory_iterator rd_iterator;
path dir2("E:\\Student");
rd_iterator end;for (rd_iterator pos(dir); pos != end; pos++)
{//如果深度大于4层,则不再继续深入
if (is_directory(*pos) && pos.level() > 4)
{pos.no_push();}//如果该目录下有nofind.txt文件,则跳出该目录
if (*pos == "nofind.txt"){pos.pop();}}
四、示例
找出指定目录及子目录下匹配的文件
#include <iostream>#include <boost/filesystem.hpp>#include <boost/xpressive/xpressive_dynamic.hpp>#include <boost/algorithm/string.hpp>
#include <vector>using namespace boost::filesystem;using namespace boost::xpressive;typedef recursive_directory_iterator rd_iterator;
//获取过滤的文件
void GetFilterFile(const std::string& filter,std::vector<path>& vecFile){path filterPath = dir / filter;path filterDir1 = filterPath.parent_path();std::string filename = filterPath.filename().string();//转换文件通配符为正则表达式
std::string str = boost::replace_all_copy(boost::replace_all_copy(filename, ".", "\\."), "*", ".*");sregex reg = sregex::compile(str);if (!exists(filterDir1) || !is_directory(filterDir1))
{return;
}//查找当前目录及子目录的所有文件,如果符合正则表达式则添加到列表中
rd_iterator end;for (rd_iterator pos(filterDir1); pos != end; pos++)
{if (!is_directory(*pos) && regex_match(pos->path().filename().string(), reg)){vecFile.push_back(pos->path());}}}