Boost教程(二)文件系统

首先在cmake中使用Boost的filesystem模块:

1
2
3
4
5
6
find_package(Boost COMPONENTS system filesystem REQUIRED)

target_link_libraries(mytarget
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
)

必须得加上system模块

filesystem库提供了两个头文件,一个是,这个头文件包含主要的库内容。它提供了对文件系统的重要操作。同时它定义了一个类path,正如大家所想的,这个是一个可移植的路径表示方法,它是filesystem库的基础。

filesystem在任何时候,只要不能完成相应的任务,它都可能抛出 basic_filesystem_error异常,当然并不是总会抛出异常,因为在库编译的时候可以关闭这个功能。

路径的创建很简单,仅仅需要向类boost::filesystem::path()的构造器传递一个string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    filesystem::path cur_path = filesystem::current_path();
filesystem::path parent_path = cur_path.parent_path();
//path支持重载/运算符,这个很好用
filesystem::path file_path = cur_path/"test";
cout<<"curren path: "<<cur_path<<endl;
cout<<"parent path: "<<parent_path<<endl;
if(filesystem::exists(file_path)) // 适合判断文件的存在
cout<<"exists test "<<endl;

filesystem::path filePath = "/home/user/yaml";
cout<<fs::is_directory(filePath)<<endl;
cout<<fs::is_empty(filePath)<<endl; // 判断是否为空

// unsigned long int, byte
cout<<"file test size: "<<filesystem::file_size(file_path)<<endl;
// filesystem::remove(file_path);
filesystem::rename(file_path, cur_path/"newTest");

filesystem::path p("/home/user/ost.yaml");
if(fs::exists(p)) // Boost缺陷,若文件不存在,两函数也能正常输出
{
cout<<p.extension()<<endl; // "yaml"
cout<<p.stem()<<endl; // 文件名,不带扩展名
}
// 删除文件,失败会强行结束:terminate called after throwing an instance of 'boost::filesystem::filesystem_error' 所以要用 try catch throw
try
{
boost::filesystem::remove(p);
}
catch( const boost::exception & e )
{
cout<< "remove error"<<endl;
throw;
// return -1;
}
filesystem::create_directory(cur_path/"dir");
cout<<"is dir: "<<filesystem::is_directory(cur_path/"dir")<<endl;

递归获取某文件夹中符合某扩展名的所有文件名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
namespace fs = boost::filesystem;

std::vector<fs::path> getFileNames(fs::path p, std::string extension)
{
std::vector<fs::path> names;

if(!fs::is_directory(p) )
return names;

if(fs::is_empty(p))
return names;

fs::recursive_directory_iterator iter(p); //迭代目录下的所有文件
fs::recursive_directory_iterator end_iter; // 只接就是end iterator
if( !p.empty() && fs::exists(p))
{
for(; iter!= end_iter;iter++)
{
try{
if (fs::is_directory( *iter ) )
{
// std::cout<<*iter << "is dir" << std::endl;
}
else
{
// std::cout<<iter->path().stem() <<endl;
// std::cout<<iter->path().extension() <<endl;
// std::cout << "full name: "<<*iter << endl;
if(iter->path().extension() == extension)
{
names.push_back(iter->path().stem());
}
}
}
catch ( const std::exception & ex ){
std::cerr << ex.what() << std::endl;
continue;
}
}
}
return names;
}

// 使用
std::vector<fs::path> names = getFileNames("/home/zzp/yaml", ".yaml");
if(names.empty())
{
cout<<"It's empty or not a dir"<<endl;
return -1;
}
else
{
for(int i=0;i<names.size();i++)
cout<<"name: "<<names.at(i)<<endl;
}