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();

}

}

*/

时间: 2024-07-28 21:37:06

BOOST 库中filesyatem 库的学习的相关文章

boost库中的 program_options

1.阅读rviz中的源码时在rviz/visualizer_app.cpp中遇到如下代码: po::options_description options; options.add_options() ("help,h", "Produce this help message") ("splash-screen,s", po::value<std::string>(), "A custom splash-screen ima

Boost库中shared_ptr(上)

1.共享性智能指针(shared_ptr) 引用计数型指针 shared_ptr是一个最像指针的"智能指针",是boost.smart_ptr库中最有价值,最重要,也是最有用的.  shared_ptr实现的是引用技术型的智能指针,可以被拷贝和赋值,在任意地方共享它,当没有代码使用(此时引用         计数为0)它才删除被动态分配的对象.shared_ptr也可以被安全的放到标准容器中: 2.怎么使用shared_ptr 举一个操作的例子: #include<iostrea

模拟实现c++标准库和boost库中的智能指针

我们知道c++标准库中定义了智能指针auto_ptr,但是我们很少用它,因为虽然它能够自动回收动态开辟的内存,不需要程序员自己去维护动态开辟的内存,但是当用它去赋值或者是拷贝构造时有一个管理权转移的过程,这样我们就不能很方便的使用auto_ptr. 下面是简单的auto_ptr的实现,我们可以看到在复制和赋值时它将转移管理权. template<class T> class AutoPtr { public:      AutoPtr(T* ptr)       :_ptr(ptr)     

Boost库中scoped_ptr

1.VC和VS VC版并不是标准C++,VS版符合标准C++,其语法相当严格. 缺点:VC和VS都只能释放一个具体类型空间,不能对数组空间进行释放,还有写时拷贝的问题:         所以引发了Boost库的出现来解决此类问题. 2.Boost库 推荐看一下Boost库完全开发指南. Boost本身是开源库,在C++中的地位举足轻重,第三章内存管理,智能指针: C++中也提供了智能指针,但是并不能解决所有问题. smart_ptr库中:new delete的运用不正确,是C++中造成资源获取/

Linux学习笔记7——linux中的静态库和动态库

一.静态库的编译 静态库的编译过程如下: 1.编译成目标文件 这里有一个可选项-static,调用格式:gcc -c -static 代码文件名.c 2.归档成静态库 A.归档的工具是ar工具,使用ar -r可以将文件归档成静态库,调用格式:ar -r 静态库文件 被归档的文件 例如:我们这有两个C文件,分别为test1.c和test2.c 首先我们将它编译成目标文件:gcc -c -static test1.c gcc -c -static test2.c 此时会产生两个文件,分别为test1

浅析muduo库中的线程设施

muduo是目前我在学习过程中遇到的最具有学习意义的网络库,下文将分析muduo库中的基础设施--Thread和ThreadPool. 首先,介绍在多线程编程中不可缺少的同步措施--Mutex和Condition. Mutex ``` /Mutex.h/ class MutexLock : boost::noncopyable { public: MutexLock() : holder_(0) { MCHECK(pthread_mutex_init(&mutex_, NULL));//MCHE

linux学习 建立静态库,动态库,写简单的makefile

建立静态库 建立四个文件 bin(可执行文件),lib(库),include(头文件),src(放源文件) 这里的起的库明为add 在src文件中执行 1)gcc -c add.c //编译add.c源文件生成add.o目标文件 2)ar crsv ../lib/ libadd.a add.o //对目标文件*.o进行归档,生成lib*.a, 把这个生成文件放在lib里 3)gcc -o main main.c -L(大些的爱偶,放库的路径)../lib   –l(小写的爱偶,库名为add) a

(转)HelloWorld CMake CMake中构建静态库与动态库及其使用

继续完善Hello World,建立它的共享库, 包括静态库和动态库. 本节的任务: 1,建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc 向终端输出Hello World字符串. 2,安装头文件与共享库. 3, 编写一个程序使用创建的共享库(静态库和动态库). cd /home/ccj/CMakeDemo mkdir t3   cd /backup/cmake/t3 mkdir lib   在t3目录下建立CMakeLists.txt,内容如下: PRO

C++ 中的共享库和静态库(Linux) (待续...)

之前学习过VC环境下的动态库.静态库 C++中的动态库和静态库 (Windows) http://zhweizhi.blog.51cto.com/10800691/1883814 而Linux环境下也有动态库.静态库,并且原理都是相似的 库: 在C/C++中,使用库(Library)的技术,可以将编译好的符号提供给第三方使用. 库有两种: 1.共享库 Shared Library    (Linux下叫做 Dynamic-Link Library (DLL),动态库) 2.静态库 Static