/*FileSyatem
库的学习------------------------------------------------------------------------------------------------------------库的使用方式嵌入源码的形式:#define
BOOST_SYSTEN_NO_LIB#define
BOOST_FILESYSTEM_NO_LIB#include<boost\filesystem.hpp>-----------------------------------------------------------------------------------------------------------类摘要filesystem
库的核心类是basic_path 通常我们不直接使用basic_path而是使用预定义的path和wpathtypedef
basic_path<std::string,path_traits>path;------------------------------------------------------------------------------------------------------------路径表示posix
语法使用斜杠(/)来分隔文件名和目录名,点号(.)表示当前目录,双点号(..)表示上一级目录path
p1("./a_dir");path
p2("/usr/local/lib");path也支持操作系统的原生路径表示比如windows下使用盘符分隔符和反斜杠(\):path
p3("c:\\temp\\test.text");path
p4("d:/boost/boostget");空的构造函数创建一个空路径对象,不表示任何路径,成员函数empty可以判断路径是否为空path
p5;assert(p.empty());path
重载了operator/=可以使用普通路径一样用/来追加路径,成员函数append()也可以追加一个字符串序列char
str[]="the path is (/root).";path
p(str+13,str+14);p/="etc";追加路径string
filename="xinetd.conf";p.append(filename.begin(),file.end());结果:p=/etc/xinetd.conf;system_complete(p)返回路径在当前文件系统中的完整文件路径--------------------------------------------------------------------------------------------------------------------可移植的文件名filesystem提供了一系列的文件名检查函数可以根据系统命名规则判断一个文件字符串是否有效portable_posix_name()和windows_name()分别检查文件名是否符合POSIX规范和windows规范函数portable_name()判断名字是否是一个可移植的文件名但名字不能以点好或者连字符开头,允许表示当前目录的“。”和父目录“..”protable_directory_name()包含了portable_name()并且要求名字不能出现点号portable_file_name()
类似protable_directory_name()它要求文件名中最多有一个点号并且后缀名不能超过三个字符filesystem
提供了一个native()函数它判断文件名是否符合本地文件系统名规则在windows等同于windows_name(),其他操作系统知识简单的判断文件名不是空格且不含斜杠---------------------------------------------------------------------------------------------------------------------路径处理path的成员函数string()返回标准格式的路径表示,directory_string()返回文件系统格式路径表
示,parent_path(),stem(),filename()和extension()分别返回路径中的父路径,不含扩张名的全路径名,文件名和 扩展名is_complete()函数检测path是否是一个完整的路径(绝对路径),这需要依据具体的文件(操作系统)系统表示root_name()和root_directory(),root_path()三个函数用于根目录的处理如果path中含有根那么他们分别返回根的名字,根目录和根路径cout<<p.root_name()<<endl;cout<<p.root_directory()<<endl;cout<<p.root_path()<<endl;这段代码在linux下输出一个空字符串和两个斜杠(/),如果path是如C:/xx/yyy的形式输出的会是
“C”,“/”,“C:/”relative_path()返回path的相对路径相当于去掉了root_path()根路径和相对路径的的四个函数都有对应的has_XXX()的形式,用来判断是否存在对应的路径has_filename()和has_parent_path()用于判断路径是否有文件名或者父路径p.has_root_name()可以修改path函数:remove_filename()可以移除路径中的最后文件名,变成纯路径replace_extension()可以变更文件的扩展名可以对两个path对象进行比较基于字典且对大小写敏感
< > == !=-----------------------------------------------------------------------------------------------------------------------------
迭代路径中的字符串path还提供迭代器
begin()和end()path
p="/boost/tools/libs"BOOST_AUTO(pos,p.begin());while(pos!=p.end()){ cout<<"["<<*pos<<"]"; ++pos;}结果[/][boost][tools][libs]如果path类提供的这些操作还不能满足要求可以使用boost库中的字符串库如string_algo--------------------------------------------------------------------------------------------------------------------------------
异常异常类是个模板类basic_filesystem_error它是system库中system_error类的子类我们通常应该使用这两个预定义的异常类typedef
basic_filesystem_error<path> filesystemerrortypedef
basic_filesystem_error<path> wfilesystemerror--------------------------------------------------------------------------------------------------------------------使用下面的代码检查文件大小但是文件不存在path
p("c:/test.txt")try{ file_size(p);}catch(filesystem_error&
e){ cout<<e.path1()<<endl; cout<<e.what()<<endl; }----------------------------------------------------------------------------------------------------------------------------------------
文件状态filesystem库提供一个文件状态类file_status以及一组相关函数,用于检查文件的各种属性,如有是否存在是否是目录,是否是符号链接等file_status的成员函数type()用于获取文件的状态他是一个枚举值通常我们不直接使用file_status而是使用使用相关的函数返回file_status对象函数status(const
Path&p)和symlink_status(const Path&p)测试路径p的状态结果可以type()如果路径不能解析则抛出异常file_type是枚举值可以是以下值:file_not_found
文件不存在status_unknow
文件存在但状态未知regular_file
是一个普通文件directory_file
是一个目录symlink_file
是一个连接文件block_file
一块设备文件character_file
一个字符设备文件fifo_file
管道设备文件socket_file
socket设备文件type_unknow
文件的类型未知assert(status("d:/boost").type()==directory_file)filesystem
库提供了一些便利的谓词函数is_XXX以简化文件状态的判断assert(is_directory("d:/boost"))大部分谓词函数望文只意比较特别的是is_other()和is_empty()但文件不是普通文件,目录或链接是,is_other()返回true对于
empty若是目录则里边没文件时返回true,若是文件 大小问0是返回true函数
equivalent()可比较两个目录实体是否是同一个----------------------------------------------------------------------------------------------------------------------------------------
文件属性受到移植性的限制filesystem提供少量的文件属性操作函数initial_path()函数返回程序启动时(进入main())的当前路径函数current_path()返回当前路径它和initial_path()都是返回完整路径函数file_size()以字节为单位返回文件的大小函数last_write_time()返回文件最后修改时间是一个time_t
类型函数space可以返回一个space_info它表明该路径下的磁盘空间分配情况struct
space_info{ uintmax_t
capacity; uintmax_t
free; uintmax_t
available;}space()函数可以这样使用const
int GBYTES=1024*1024*1024;space_info
si=space("d:/");cout<<si.capacity/GBYTES<<endl;cout<<si.available/GBYTES<<endl;---------------------------------------------------------------------------------------------------------------------------------
文件操作创建目录
create_directory()文件改名
rename()文件删除
remove(),remove_all()可以递归删除所有文件对于remove使用时要加命名空间限制,否则vc环境下的函数会将其覆盖文件拷贝
copy_file()...........------------------------------------------------------------------------------------------------------------------迭代目录filesystem
库使用basic_directory_iterator可以迭代目录下所有文件其预定义了两个迭代器类
directory_iterator 和wdirectroy_iteratorbasic_directory_iterator迭代器返回的不是path对象而是basic_directory_entry对象,但是basic_directory_entry类定义了一个到path类的转换函数可以使用path()返回路径directory_iterator只能迭代本目录中的文件不支持深度遍历目录但是可以通过递归实现void
recursive_dir(const path& dir){directory_iterator
end;for(directory_iterator
pos(dir);pos!=end;++pos)if(is_directory(*pos)){recursive_dir(*pos);}else cout<<*pos<<endl;}basic_recursive_directory_iterator类提供了目录的遍历功能它比递归的调用directory_iterator效率要高其基本功能和directory_iterator相似通常我们使用其预定义的两个类
recursive_directory_iterator和wrecursive_directory_iteratorrecursive_directory_iterator
++会使它返回目录中的下一个文件成员函数:level()返回当前目录深度
m_level,recursive_directory_iterator构造时m_level=0每深入一层m_level加1退出时减少1pop()用于退出当前目录的遍历同时--mlevel,但迭代到一个目录no_push()可以让目录不参与遍历使用recursive_directory_iterator遍历目录操作recursive_directory_iterator
end;for(recursive_directory_iterator
pos("d:/test");pos!=end;++pos)cout<<"level:"<<pos.level()<<":"<<*pos<<endl;使用no_push()让recursive_directory_iterator和directory_iterator行为相同:directory_iterator
end;for(recursive_directory_iterator
pos(dir);pos!=end;++pos)if(is_directory(*pos)){ pos.no_push();}else cout<<*pos<<endl;----------------------------------------------------------------------------------------------------------------------------------------------
文件流操作filesystem
库提供大量的文件系统操作方法,可以方便的操作文件或者目录,但他使用的是path对象C++标准库中的文件流类ifstream/ofstream/ftream只支持char*打开文件,因此使用时我们必须调用path对象的string()方法然后把string转化为C字符串path
p("d:/boost/Readme.txt");std::ifstream
ifs(p.string().c_str());filesystem
库在额外的头文件<boost/filesystem/fstream.hpp>中提供在命名空间boost::filesystem下的同文件流类他们可以如标准文件流一样使用而且支持path对象使用方法:#include<>boost/filesystem/fstream.hpp>namespace
newfs=boost::filesystem;int
main(){ path
p("d:/boost/readme.txt"); newfs::ifstream
ifs(p.string().c_str()); assert(ifs.is_open()); cout<<ifs.rdbuf();}---------------------------------------------------------------------------------------------------------------------------------------------
实例一之文件查找#include<string>#include<boost/filesystem.hpp>#include<boost/optional.hpp>using
namespace std;using
namespace boost::filesystem;using
namespace boost;optional<path>
find_file(const path& dir, const string&filename){typedef
optional<path> result_type;if
(!exists(dir) || !is_directory(dir))return
result_type();recursive_directory_iterator
end;for
(recursive_directory_iterator pos(dir); pos != end; ++pos){if
(!is_directory(*pos) && pos->path().filename() == filename)return
result_type(pos->path());}return
result_type();}void
main(){optional<path>
r = find_file("G:\\TEST", "1122.txt");if
(r)cout
<< *r << endl;elsecout
<< "file not found" << endl;}---------------------------------------------------------------------------------------------------------------------------------------
实例二文件名的模糊查询void
find_files(const path& dir, const string&filename,vector<path>v){static
xpressive::sregex_compiler rc;//正则表达式工厂if
(!rc[filename].regex_id()){string
str = replace_all_copy(replace_all_copy(filename, ".", "\\."), "*", ".*");//处理文件名rc[filename]
= rc.compile(str);//创建正则表达式}typedef
vector<path> result_type;if
(!exists(dir) || !is_directory(dir)){return
;}recursive_directory_iterator
end;for
(recursive_directory_iterator pos(dir); pos != end; ++pos){if
(!is_directory(*pos) && regex_match(pos->path().filename(), rc[filename])){v.push_back(pos->path());}}}-------------------------------------------------------------------------------------------------------------------------------------
实例三目录拷贝size_t
copy_files(const path& from_dir, const path& to_dir, const string& filename = "*"){if
(!is_directory(from_dir)){cout
<< "args is not a dir" << endl;return
0;}cout
<< "prepare for copy,please wait......" << endl;vector<path>v;find_files(from_dir,
filename, v);if
(v.empty()){cout
<< "0 file copied" << endl;return
0;}cout
<< "now begin copy files......" << endl;path
tmp;progress_display
pd(v.size());BOOST_FOREACH(path&
p, v)//for_each 算法{tmp
= to_dir / p.string().substr(from_dir.string().length());if
(!exists(tmp.parent_path()))create_directories(tmp.parent_path());copy_file(p,
tmp);++pd;cout
<< v.size() << "file copied" << endl;return
v.size();} }*/
本文详细介绍了Boost FileSystem库的使用方法,包括路径表示、文件名检查、路径处理等核心功能,并通过实例展示了文件查找、模糊查询及目录拷贝的具体实现。
4916

被折叠的 条评论
为什么被折叠?



