BOOST 库中filesyatem 库的学习

分享到:
/*FileSyatem 库的学习
------------------------------------------------------------------------------------------------------------库的使用方式
嵌入源码的形式:
#define BOOST_SYSTEN_NO_LIB
#define BOOST_FILESYSTEM_NO_LIB
#include<boost\filesystem.hpp>
-----------------------------------------------------------------------------------------------------------类摘要
filesystem 库的核心类是basic_path 通常我们不直接使用basic_path而是使用预定义的path和wpath
typedef 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> filesystemerror
typedef 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_iterator
basic_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_iterator
recursive_directory_iterator ++会使它返回目录中的下一个文件
成员函数:
level()返回当前目录深度 m_level,recursive_directory_iterator构造时m_level=0每深入一层m_level加1退出时减少1
pop()用于退出当前目录的遍历同时--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;
else
cout << "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();
}
}
*/


昵    称:
验证码:

相关文档:

  • 轻量级CPP开发框架 RLIB
    RLIB是一款轻量级的C++开发框架, 提供一些常见的编程任务, 采用类似C#的命名方式....
  • C语言的BASE64处理 b64
    b64 是很很小型的、简单而且搞笑的 Base64 编码和解码的 C 语言库,无需依赖其他第三方的程序库,支持各种操作系统。同时也包含一个灵...
  • 使用libcurl 函数库获取网页数据代码
    使用libcurl 函数库获取网页数据代码...
  • C++多媒体处理库 libCVD
    libCVD 是一个高可移植和具备高性能的用于处理计算机视觉、图像、视频的C++库。其重点是提供简单高效的高质量的图形和视频处理方法...
  • 嵌入式GLIBC EGLIBC
    Embedded GLIBC (EGLIBC) 是 GNU C Library (GLIBC) 的一个变种,用于工作在嵌入式的系统中。EGLIBC 严格兼容二进制的 GLIBC 。...
  • YAML的C语言解析包 LibYAML
    LibYAML 是一个 C 语言的包,用来解析 YAML 1.1 数据。...
  • C++模板库 libsigc++
    libsigc++是实现类型安全回调的一个C++模板库。...
  • 跨平台的C++公共库:Dlib
    DLIB是一个通用的跨平台的C+ +库使用契约编程和现代C + +技术设计。...
  • C++动态编译工具 ccbuild
    ccbuild 更像是一个动态的 Makefile 。ccbuild 查找当前目录所有包含 main 方法的程序并进行构建。因此它会读取 C++ 源码并查找出依赖的文件...
  • PSD文件解析库 libspsd
    libspsd 是一个用来读取 PhotoShop 的 psd 文件格式的 C 语言开发库,支持 Adobe Photoshop CS 以及之前的版本。...
  • 用c语言实现的多平台开发库:TBOX
    TBOX是一个用c语言实现的多平台开发库,支持 windows、linux、mac、ios、android 以及其他嵌入式系统。...
  • 异步串口库函数 libcssl
    Columbo Simple Serial Library (libcssl) 是一个易用的事件驱动的串口通讯库,用于 Linux。...
  • 嵌入式开发中的C容器类 FooLib
    FooLib 是一个用c实现了常用的容器,如果rbtree,hashtable,list,vector,deque,heap,map,以及定时器,os api,应用开发框架。 实现了一个基于btree索引...
  • 便携式外部函数接口库:LibFFI
    “FFI” 的全名是 Foreign Function Interface,通常指的是允许以一种语言编写的代码调用另一种语言的代码。而 “Libffi” 库只提供了最底层的...
  • 顶级域名抽取C语言库 libtld
    libtld 是一个用来从 URI 中抽取 TLD(顶级域名) 信息的 C 库。你可以提取域名、子域名等信息...
  • C++加密/解密库:libsodium
    libsodium 是一个流行、易于使用的软件库。主要用于加密、解密、签名和生成密码哈希等等。这是一个可移植的、跨编译器支持、可安装...
  • 常用C语言函数库 libasn
    libasn 提供了一些编程里非常有用的功能和函数库(C语言),例如列表、哈希表、拓扑排序、内存管理、垃圾收集、应用层调试、正则表...
  • C++的数据库访问层 Tntdb
    Tntdb 是一个 C++ 的类库用于访问数据库,实现了数据库独立的访问层,运行时加载驱动,当前支持 postgresql, sqlite3, mysql 和 oracle...
  • 高性能c++网络库:libtnet
    libtnet是一个用c++编写的高性能网络库,它在设计上面主要参考tornado,为服务端网络编程提供简洁而高效的接口,非常易于使用。...
  • C++ 解析器线程的传播库:libpondyparser
    libpondyparser 是另一个使用 Markov 模型的多核 C++ 解析器线程的传播库,包含了一个使用增强学习传播的线程来打包一个指向统计解析库的...