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

本文深入讲解Boost.Filesystem库的核心类path的使用方法,包括路径构造、属性操作、文件时间修改、磁盘空间查询等。同时介绍了如何使用该库进行目录创建、删除、文件复制,并通过实例展示了文件查找、模糊搜索和目录文件拷贝的功能。
917

被折叠的 条评论
为什么被折叠?



