文件操作是编程中非常重要的一个部分,filesystem库是一个可移植的文件系统操作库,它使用POSIX标准文件系统的路径,接口很类似标准库的容器和迭代器,使C++具有了类似脚本余姚的功能,可以跨平台操作目录、文件,写出通用的脚本程序。
path初识
filesystem库的核心类是path,它屏蔽了不同文件系统的差异,使用可移植的POSIX语法提供了通用的目录,路径表示。
简单的sample如下:
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
char str[] = "the path is (/root).";
path p( str + 13, str + 14 );
assert( !p.empty() );
p /= "home";
string dirname = "pi";
p.append( dirname.begin(), dirname.end() );
p += "/";
p.contcat( ".bashrc" );
cout << p << endl;
// "/home/pi/.bashrc"
文件名合法性检查
filesystem提供了一系列的文件名检查函数,可以根据系统的命名规则判断一个文件名是否合法: portable_posix_name()
POSIX文件名规范检查 windows_name()
Windows文件名规范检查 portable_name()
相当于portable_posix_name() && windows_name(),但名字不能以点号或者连字符开头,保证文件名可以移植到所有操作系统。 portable_directory_name()
判断更严格,包含portable_name(),并且要求名字中不能出现点号。 portable_file_name()
类似portable_directory_name(),要求文件名最多有一个点号,且后缀不能超过3个字符。
路径处理
path的三个成员root_name(), root_directory(), root_path()用于处理根目录
path p("/usr/local/include/xxx.hpp" );
cout << p.root_name() << endl; // ""
cout << p.root_directory() << endl; // "/"
cout << p.root_path() << endl; // "/"
path p( "c:/windows/system32" );
cout << p.root_name() << endl; // "c:"
cout << p.root_directory() << endl; // "/"
cout << p.root_path() << endl; // "c:/"
文件状态
- is_directory()
- exist()
- is_empty()
- is_regular_file()
文件属性
- initial_path(): 程序启动时(进入main()函数)的当前路径;
- current_path(): 返回当前路径;
- file_size(): 以字节为单位返回文件的大小;
- last_write_time(): 文件的最后修改时间;
文件操作
- remove(): 只能删除空目录或者文件
- remove_all(): 可以递归删除
- create_directory()
- copy_file()
- rename()
- create_directories()
迭代目录
- directory_iterator
directory_iterator end;
for( directory_iterator pos( "/home/chrono/boost/" ); pos != end; ++pos ) {
cout << *pos << endl;
}
// define a std:pair range for simplifying
typedef std::pair<directory_iterator, directory_iterator> dir_range;
dir_range dr( director_iterator( "/home/chrono/boost/" ), director_iterator() );
BOOST_FOREACH( auto& x, dr ) {
cout << x << endl;
}
directory_iterator迭代器返回的对象不是path,而是一个directory_entry,但是由于directory_entry类定义了一个到path的类型转换函数,因此可以在需要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;
}
}
}
- recursive_directory_iterator
成员函数level()返回当前目录深度;
成员函数pop()用于退出当前层次的遍历;
no_push()可以让目录不参与遍历;
typedef recursive_directory_iterator rd_iterator;
rd_iterator end;
for( rd_iterator pos( "/home/chrono/test" ); pos != end; ++pos ) {
cout << "level" << pos.level() << ":" << *pos << endl;
}
// sample of no_push()
rd_iterator end;
for( rd_iterator pos( "/home/chrono/test" ); pos != end; ++pos ) {
if( is_directory( *pos ) {
pos.no_push();
}
cout << *pos << endl;
}