CMakeList.txt:
1 cmake_minimum_required(VERSION 3.8) 2 project(Demo) 3 4 set(CMAKE_CXX_STANDARD 11) 5 6 set(SOURCE_FILES main.cpp) 7 8 //需要添加filesystem组件 9 find_package(Boost REQUIRED COMPONENTS system filesystem) 10 11 if (Boost_FOUND) 12 INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) 13 add_executable(Demo ${SOURCE_FILES}) 14 target_link_libraries(Demo ${Boost_LIBRARIES}) 15 endif () 16 17 find_package(Boost REQUIRED COMPONENTS system)
boost::filesystem
boost::filesystem库的核心类是path类,他屏蔽了不同文件系统的差异,使用了可移植的POSIX语法提供了通用的目录和路径表示,并且支持POSIX的符号链接
boost::filesystem::path
path的构造函数可接受char*类型和string类型的参数构造,也可以是一个字符串迭代范围,路径的分割符由constexpr preferred_separator定义,UNIX是正斜杠(/),WINDOWS是反斜杠(),C++中需要转义;
path使用的是POSIX语法标准,使用正斜杠(/)来分割目录,(./)代表当前路径,(..)代表当前目录上层;
path类中基本实现了大部分文件属性操作,具体查看官方文档,以下只做了少部分测试
基本方法:
1 #include <iostream> 2 #include <boost/filesystem.hpp> 3 4 5 int 6 main(int argc, char **argv) 7 { 8 //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理 9 try 10 { 11 //unix 12 boost::filesystem::path path1("./Demo/Demo.txt"); 13 //windows 14 boost::filesystem::path path2("C:\Boost\Demo\include\"); 15 16 //空路径,可用empty()判断 17 boost::filesystem::path path3; 18 assert(path3.empty()); 19 20 //path构造时不会检查路径的合法性(可使用函数判断) 21 boost::filesystem::path path4("asdwqdqdasd"); 22 23 24 boost::filesystem::path path5("/usr/local/include/"); 25 auto path6 = path5 / "boost/filesystem/"; //path重载了operator/()方法可追加路径 26 std::cout << path6 << std::endl; //path重载operator<<方法输出 27 std::cout << path6.string() << std::endl; //返回string的方法,可用于C++中的fstream 28 std::cout << path6.parent_path() << std::endl; //父路径 29 std::cout << path6.filename() << std::endl; //文件 30 std::cout << path6.stem() << std::endl; //不带扩展名的文件名 31 std::cout << path6.extension() << std::endl; //扩展名 32 33 34 //唯一两个可修改路径函数 35 path6.replace_extension("ini"); //修改文件后缀名 36 std::cout << path6 << std::endl; //"/usr/local/include/boost/filesystem/.ini" 37 path6.remove_filename(); //移除文件名 38 std::cout << path6 << std::endl; //"/usr/local/include/boost/filesystem" 39 40 41 //path中有begin 和 end 迭代器,可以循环得出目录名 42 for (auto &iter:path6) 43 { 44 std::cout << "[" << iter << "]" << std::endl; 45 } 46 /*["/"] 47 ["usr"] 48 ["local"] 49 ["include"] 50 ["boost"] 51 ["filesystem"]*/ 52 53 54 //// file_type // 55 ////--------------------------------------------------------------------------------------// 56 // 57 // enum file_type 58 // { 59 // status_error, 60 //# ifndef BOOST_FILESYSTEM_NO_DEPRECATED 61 // status_unknown = status_error, 62 //# endif 63 // file_not_found, 64 // regular_file, 65 // directory_file, 66 // // the following may not apply to some operating systems or file systems 67 // symlink_file, 68 // block_file, 69 // character_file, 70 // fifo_file, 71 // socket_file, 72 // reparse_file, // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink 73 // type_unknown, // file does exist, but isn't one of the above types or 74 // // we don't have strong enough permission to find its type 75 // 76 // _detail_directory_symlink // internal use only; never exposed to users 77 // }; 78 79 std::cout << boost::filesystem::status(path6).type() << std::endl; //文件类型 80 std::cout << boost::filesystem::symlink_status(path6).type() << std::endl; 81 std::cout << boost::filesystem::directory_file << std::endl; 82 std::cout << boost::filesystem::status(path6).permissions() << std::endl; //文件的权限等级 83 84 85 } 86 catch (boost::filesystem::filesystem_error &e) 87 { 88 std::cout << e.path1() << std::endl; 89 std::cout << e.path2() << std::endl; 90 std::cout << e.what() << std::endl; 91 } 92 93 94 return 0; 95 } 96
查看磁盘和当前路径,修改文件时间(linux::touch)
1 #include <iostream> 2 #include <boost/filesystem.hpp> 3 #include <boost/ratio.hpp> 4 5 int 6 main() 7 { 8 //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理 9 try 10 { 11 12 boost::filesystem::path path("/Users/xuaidong/Desktop/test.txt"); 13 boost::filesystem::path path1("/Users/xuaidong"); 14 //进入(程序启动时)main函数时的路径 15 std::cout << boost::filesystem::initial_path() << std::endl; 16 //返回当前路径,和initial_path()都是返回绝对路径(完整路径) 17 std::cout << boost::filesystem::current_path() << std::endl; 18 19 20 assert(boost::filesystem::is_regular_file(path)); 21 22 //返回文件最后一次修改时间 23 std::cout << boost::filesystem::last_write_time(path) << std::endl; 24 //更改文件修改时间(linux touch) 25 boost::filesystem::last_write_time(path, time(0)); 26 std::cout << boost::filesystem::last_write_time(path) << std::endl; 27 28 //查看磁盘空间 29 30 boost::filesystem::space_info sp = boost::filesystem::space(path); 31 std::cout << "磁盘空间: " << sp.capacity / boost::giga::num << std::endl; 32 std::cout << "磁盘可用空间: " << sp.free / boost::giga::num << std::endl; 33 std::cout << "磁盘可用空间: " << sp.available / boost::giga::num << std::endl; 34 35 36 std::cout << boost::filesystem::file_size(path) << std::endl; 37 38 39 } 40 catch (boost::filesystem::filesystem_error &e) 41 { 42 43 std::cout << e.path1() << std::endl; 44 std::cout << e.path2() << std::endl; 45 std::cout << e.what() << std::endl; 46 } 47 48 49 return 0; 50 } 51
创建目录,删除目录,拷贝文件
1 #include <iostream> 2 #include <boost/filesystem.hpp> 3 #include <boost/ratio.hpp> 4 5 int 6 main(int argc, char **argv) 7 { 8 //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理 9 try 10 { 11 boost::filesystem::path path("/Users/xuaidong/Desktop/ABABAB"); 12 13 //assert(boost::filesystem::is_regular_file(path)); 14 assert(boost::filesystem::is_directory(path)); 15 16 //删除空目录/文件 17 //boost::filesystem::remove(path); 18 //递归删除多个目录或者文件 19 boost::filesystem::remove_all(path); 20 21 22 //根据path创建一个目录 23 boost::filesystem::create_directories(path); 24 assert(boost::filesystem::exists(path)); 25 //拷贝文件到这个目录下 26 boost::filesystem::copy_file("/Users/xuaidong/Desktop/Some.txt", path / "Some2.txt"); 27 28 //重命名 29 boost::filesystem::rename(path/"Some2.txt",path/"Demo.txt"); 30 31 //创建多及目录 32 boost::filesystem::create_directories(path/"Director1"/"Director2"/"Director3"); 33 34 35 } 36 catch (boost::filesystem::filesystem_error &e) 37 { 38 39 std::cout << e.path1() << std::endl; 40 std::cout << e.path2() << std::endl; 41 std::cout << e.what() << std::endl; 42 } 43 44 45 return 0; 46 } 47
使用boost::filesystem::director_iterator迭代当前目录下文件(不向下层目录迭代),但是也可实现目录下层目录循环递归,其实boost也提供了boost::filesystem::recursive_directory_iterator向下递归而且遍历目录是可控制的(深度/浅度),且速度比递归的director_itertaor快
1 #include <iostream> 2 #include <boost/filesystem.hpp> 3 #include <boost/ratio.hpp> 4 5 void resource_direction(const boost::filesystem::path& path) 6 { 7 //递归文件目录下的所有文件路径 8 boost::filesystem::directory_iterator end; 9 for(boost::filesystem::directory_iterator begin(path);begin!=end;begin++) 10 { 11 //如果是目录继续向下解析 12 if (boost::filesystem::is_directory(*begin)) 13 resource_direction(*begin); 14 else 15 std::cout<<*begin<<std::endl; 16 17 } 18 19 } 20 21 22 int 23 main(int argc, char **argv) 24 { 25 //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理 26 try 27 { 28 boost::filesystem::path path("/Users/xuaidong/Desktop/"); 29 resource_direction(path); 30 31 } 32 catch (boost::filesystem::filesystem_error &e) 33 { 34 35 std::cout << e.path1() << std::endl; 36 std::cout << e.path2() << std::endl; 37 std::cout << e.what() << std::endl; 38 } 39 40 41 return 0; 42 } 43 44 45 46 //系统提供的文件目录遍历 47 #include <iostream> 48 #include <boost/filesystem.hpp> 49 #include <boost/ratio.hpp> 50 #include <map> 51 #include <vector> 52 #include <string> 53 #include <memory> 54 55 56 int 57 main(int argc, char **argv) 58 { 59 //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理 60 try 61 { 62 std::map<int64_t, std::shared_ptr<std::vector<std::string>>> dir_map; 63 //boost深度遍历目录和浅度遍历 64 //默认构造是尾迭代器 65 boost::filesystem::recursive_directory_iterator end; 66 for (boost::filesystem::recursive_directory_iterator iter("/Users/xuaidong/Desktop"); iter != end; iter++) 67 { 68 //std::cout << "directory_level: " << iter.level() << "file path: " << *iter << std::endl; 69 if (boost::filesystem::is_directory(*iter)) 70 { 71 iter.no_push(); 72 } //不深度便利 73 //iter.pop() 退出当前目录的遍历 74 75 auto &ptr = dir_map[iter.level()]; 76 if (!ptr) 77 ptr.reset(new std::vector<std::string>); 78 79 ptr->push_back(iter->path().string()); 80 81 } 82 83 for (auto &iter1:dir_map) 84 { 85 for (auto &iter2:*(iter1.second)) 86 { 87 std::cout << "directory_level: " << iter1.first << ", file path: " << iter2 << std::endl; 88 } 89 } 90 91 } 92 catch (boost::filesystem::filesystem_error &e) 93 { 94 95 std::cout << e.path1() << std::endl; 96 std::cout << e.path2() << std::endl; 97 std::cout << e.what() << std::endl; 98 } 99 100 101 return 0; 102 } 103 104
实例1:实现简单文件查找
1 #include <iostream> 2 #include <boost/filesystem.hpp> 3 #include <boost/ratio.hpp> 4 #include <boost/optional.hpp> 5 6 //boost filesystem realize find file 7 8 boost::optional<boost::filesystem::path> find_file(const boost::filesystem::path& path,const std::string& file) 9 { 10 typedef boost::optional<boost::filesystem::path> result_value; 11 if (!boost::filesystem::exists(path)&&!boost::filesystem::is_directory(path)) 12 return result_value(); 13 14 //递归目录查找 15 boost::filesystem::recursive_directory_iterator end; 16 for(boost::filesystem::recursive_directory_iterator iter(path);iter!=end;++iter) 17 { 18 if (!boost::filesystem::is_directory(*iter)&&iter->path().filename()==file) 19 return result_value(iter->path()); 20 } 21 22 return result_value(); 23 } 24 25 26 27 int 28 main(int argc, char **argv) 29 { 30 //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理 31 try 32 { 33 auto path=find_file("/Users/xuaidong/Desktop/","application.cpp"); 34 35 if (path) 36 { 37 std::cout<<"CMakeLists.txt is here: "<<*path<<std::endl; 38 }else 39 { 40 std::cout<<"CMakeLists.txt not to find"<<std::endl; 41 } 42 43 44 45 } 46 catch (boost::filesystem::filesystem_error &e) 47 { 48 49 std::cout << e.path1() << std::endl; 50 std::cout << e.path2() << std::endl; 51 std::cout << e.what() << std::endl; 52 } 53 54 55 return 0; 56 } 57
实例2:利用boost::xpressive正则匹配实现模糊查找(只实现"*"匹配)
1 #include <iostream> 2 #include <string> 3 #include <boost/filesystem.hpp> 4 #include <boost/xpressive/xpressive.hpp> 5 #include <boost/algorithm/string.hpp> 6 7 //boost filesystem realize obscure find file 8 9 std::vector<boost::filesystem::path> 10 find_file(const boost::filesystem::path &path, const std::string &file) 11 { 12 13 //之后查找使用- - 14 static boost::xpressive::sregex_compiler rc; //正则表达式工厂 15 if (!rc[file].regex_id()) 16 { 17 std::string str = boost::replace_all_copy(boost::replace_all_copy(file, ".", "\."), "*", ".*"); 18 rc[file] = rc.compile(str); 19 } 20 21 22 typedef std::vector<boost::filesystem::path> result_value; 23 result_value v; 24 if (!boost::filesystem::exists(path) && !boost::filesystem::is_directory(path)) 25 { 26 return v; 27 } 28 29 //递归目录查找 30 boost::filesystem::recursive_directory_iterator end; 31 for (boost::filesystem::recursive_directory_iterator iter(path); iter != end; ++iter) 32 { 33 if (!boost::filesystem::is_directory(*iter) && 34 boost::xpressive::regex_match(iter->path().filename().string(), rc[file])) 35 { 36 v.push_back(iter->path()); 37 } 38 } 39 40 return v; 41 } 42 43 44 int 45 main(int argc, char **argv) 46 { 47 //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理 48 try 49 { 50 auto path = find_file("/Users/xuaidong/Desktop/", "*.txt"); 51 52 for (auto &iter:path) 53 { 54 std::cout << "file match: " << iter << std::endl; 55 } 56 57 58 } 59 catch (boost::filesystem::filesystem_error &e) 60 { 61 62 std::cout << e.path1() << std::endl; 63 std::cout << e.path2() << std::endl; 64 std::cout << e.what() << std::endl; 65 } 66 67 68 return 0; 69 } 70
实例3:实现目录文件拷贝(空目录也考了)
1 #include <iostream> 2 #include <string> 3 #include <boost/filesystem.hpp> 4 #include <boost/xpressive/xpressive.hpp> 5 #include <boost/algorithm/string.hpp> 6 #include <boost/progress.hpp> 7 8 9 std::vector<boost::filesystem::path> 10 find_file(const boost::filesystem::path &path, const std::string &file) 11 { 12 13 //之后查找使用- - 14 static boost::xpressive::sregex_compiler rc; //正则表达式工厂 15 if (!rc[file].regex_id()) 16 { 17 std::string str = boost::replace_all_copy(boost::replace_all_copy(file, ".", "\."), "*", ".*"); 18 rc[file] = rc.compile(str); 19 } 20 21 22 typedef std::vector<boost::filesystem::path> result_value; 23 result_value v; 24 if (!boost::filesystem::exists(path) && !boost::filesystem::is_directory(path)) 25 { 26 return v; 27 } 28 29 //递归目录查找 30 boost::filesystem::recursive_directory_iterator end; 31 for (boost::filesystem::recursive_directory_iterator iter(path); iter != end; ++iter) 32 { 33 if (boost::xpressive::regex_match(iter->path().filename().string(), rc[file])) 34 { 35 v.push_back(iter->path()); 36 } 37 } 38 39 return v; 40 } 41 42 43 std::size_t 44 copy_files( 45 const boost::filesystem::path &from_dir, 46 const boost::filesystem::path &to_dir, 47 const std::string &filename = "*" 48 ) 49 { 50 if (!boost::filesystem::exists(from_dir)) 51 { 52 std::cout << "file not find" << std::endl; 53 return -1; 54 } 55 56 57 std::cout << "prepare copy please wait....." << std::endl; 58 auto vcontain = find_file(from_dir, filename); 59 60 if (vcontain.empty()) 61 { 62 std::cout << "file is empty" << std::endl; 63 return -1; 64 } 65 66 67 boost::filesystem::path temp; 68 boost::progress_display display(vcontain.size()); 69 70 for (auto &iter:vcontain) 71 { 72 temp = to_dir / iter.string().substr(from_dir.string().length()); 73 std::cout << "file: " << temp << std::endl; 74 if (!boost::filesystem::exists(temp.parent_path())) 75 { 76 boost::filesystem::create_directories(temp.parent_path()); 77 } 78 79 if(boost::filesystem::is_directory(iter)) 80 { 81 boost::filesystem::create_directories(temp); 82 } 83 else{ 84 boost::filesystem::copy_file(iter, temp, boost::filesystem::copy_option::overwrite_if_exists); 85 } 86 87 ++display; 88 } 89 90 std::cout << vcontain.size() << " filed copyed" << std::endl; 91 92 return vcontain.size(); 93 94 } 95 96 97 int 98 main(int argc, char **argv) 99 { 100 //因为文件属于程序外的不可控资源,随时抛出异常,try{}catch处理 101 try 102 { 103 copy_files("/Users/xuaidong/Desktop/Boost", "/Users/xuaidong/Desktop/Test"); 104 105 106 } 107 catch (boost::filesystem::filesystem_error &e) 108 { 109 110 std::cout << e.path1() << std::endl; 111 std::cout << e.path2() << std::endl; 112 std::cout << e.what() << std::endl; 113 } 114 115 116 } 117