Boost filessystem...

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   

 

posted @ 2017-08-05 21:55  FeckCode  阅读(315)  评论(0编辑  收藏  举报