在BOOST库出现以前,C++对于文件和目录的操做,大都借助于UNIX提供的底层文件和目录接口,从使用角度来看,这些底层的操做不够友好。BOOST中filesystem库是一种可移植的文件系统操做库,能够跨平台的操做目录、文件等,在不失性能的状况下,提供了友好的操做方法。
本文主要介绍在UNIX环境中,boost::filesystem的经常使用操做方法。
假设你已经安装好了boost库,使用boost::filesystem须要加上头文件windows
#include <boost/filesystem.hpp>
编译时,须要连接ruby
-lboost_filesystem
当安装路径不是UNIX环境变量中设置的标准路径的话,编译时还需加上boost库头文件和动态路路径,即:函数
-I $(BOOST)/include/ -L $(BOOST)/lib/
变量$(BOOST)是BOOST库实际安装路径。性能
filesystem库是一个可移植的文件系统操做库,它在底层作了大量的工做,使用POSIX标准表示文件系统的路径,使C++具备了相似脚本语言的功能,能够跨平台操做目录、文件,写出通用的脚本程序。ui
1.path的构造函数能够接受C字符串和string,也能够是一个指定首末迭代器字符串序列区间。spa
2.filesystem提供了一系列的文件名(或目录)检查函数。code
3.有丰富的函数用于获取文件名、目录名、判断文件属性等等。对象
4.filesystem库使用异常来处理文件操做时发生的错误。blog
5.filesystem库提供一个文件状态类file_status及一组相关函数,用于检查文件的各类属性,如是否存在、是不是目录、是不是符号连接等。递归
6.filesystem提供了少许的文件属性操做,如windows下的只读、归档等,Linux下的读写权限等。
7.文件操做,如建立目录、文件更名、文件删除、文件拷贝等等。
8.basic_directory_iterator提供了迭代一个目录下全部文件的功能。
//注意 /= 和 += 的区别, /= 表示追加下级目录, += 仅仅是字符串的串接 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);// 创建路径
路径(path类)和迭代器–filesystem操做的基础
path类提供了路径操做的丰富接口,能够得到文件名、拓展名、文件属性等。迭代器提供了遍历整个目录全部文件的功能,经常使用的filesystem库的迭代器是:directory_iterator和recursive_directory_iterator,后者相对于前者提供了递归遍历的功能。
基于路径和迭代器,下文已迭代目录(cur/)为例,简介filesystem的基本操做:
首先,定义要处理文件的路径
string curPath = “/home/test/cur/” ;
条件假设:
1).cur目录下结构以下
cur/
—build.sh
—src/
——main.cpp
——makefile
2).进入/home/test/cur目录,执行build.sh编译程序后,留在当前目录执行可执行文件
3).假设程序扫描目录时,首先扫描到的文件时 build.sh
//定义一个能够递归的目录迭代器,用于遍历 boost::filesystem::recursive_directory_iterator itEnd; for(boost::filesystem::recursive_directory_iterator itor( curPath.c_str() ); itor != itEnd ;++itor) { //itor->path().string()是目录下文件的路径 /* *当curPath是相对路径时,itor->string()也是相对路径 *即当curPath = "../cur/",下面将输出"../cur/build.sh" */ //当curPath是绝对路径时,itor->string()也是绝对路径 string file = itor->path().string() ; // "/home/test/cur/build.sh" //构造文件路径,以得到文件丰富的操做 //path能够接受C风格字符串和string类型做为构造函数的参数,而提供的路径能够是相对路径,也能够是绝对路径。 boost::filesystem::path filePath(file); //path的方法如filename()等,返回的对象还是path,若是能够经过path的string()方法,获取对象的string类型 //parent_path()得到的是当前文件的父路径 cout<<filePath.parent_path()<<endl; // "/home/test/cur/" //filename()得到的是文件名,含拓展名 cout<<filePath.filename()<<endl; // "build.sh" cout<<filePath.filename().string()<<endl; //stem()得到的是文件的净文件名,即不含拓展名 cout<<filePath.stem()<<endl; // "build" //extension()文件的拓展名(主要是".sh"而不是"sh") cout<<filePath.extension()<<endl; // ".sh" //得到文件的大小,单位为字节 int nFileSize = boost::filesystem::file_size(filePath); //最后一次修改文件的时间 //last_write_time()返回的是最后一次文件修改的绝对秒数 //last_write_time(filePath,time(NULL))还能够修改文件的最后修改时间,至关于Linux中命令的touch if(filePath.last_write_time() - time(NULL) > 5) { /* *在工程实践中,当须要不断的扫目录,而目录又会不断的加入新文件时, *借助last_write_time()能够判断新入文件的完整性,以免错误的处理还未写完的文件 */ } //判断文件的状态信息 if(boost::filesystem::is_regular_file(file)) { //is_regular_file(file)普通文件 //is_directory(file)目录文件,如当遍历到"/home/test/cur/src/"时,这就是一个目录文件 //is_symlink(file)连接文件 ... } //更改拓展名 boost::filesystem::path tmpPath = filePath; //假设遍历到了cpp文件,想看下对应的.o文件是否存在 tmpPath.replace_extension(".o"); //判断文件是否存在 if( boost::filesystem::exists( tmpPath.string() ) ) //删除文件 //remove只能删除普通文件,而不能删除目录 boost::filesystem::remove(tmpPath.string()); //remove_all则提供了递归删除的功能,能够删除目录 boost::filesystem::remove_all(tmpPath.string()); //移动文件 & 拷贝文件 //srcPath原路径,srcPath的类型为string //destPath目标路径,destPath的类型为string boost::filesystem::rename(srcPath , destPath); boost::filesystem::copy_file(srcPath , destPath); //拷贝目录 boost::filesystem::copy_files("/home/test","/dev/shm") } boost::filesystem还能够建立目录: if( !boost::filesystem::exists( strFilePath ) ) { boost::filesystem::create_directories(strFilePath) }
boost::filesystem提供的操做固然不仅如此,详见参考文件1。使用boost::filesystem操做时加上异常捕获,也可以增长代码的鲁棒性,在此不进行累述。