Boost库学习(6)filesystem

本文介绍如何利用Boost的filesystem库进行文件路径处理、目录遍历、文件新建与查找,以及如何在命令行程序中实现复杂文件操作。

C++中标准中,只提供了对特定文件的读写操作方法,而没有定义对于文件路径的操作方法,而在编写代码时,经常中要对文件路径进行处理的(文件是否存在,复制、遍历文件目录等)。如果是GUI程序,可以用QT一类的UI库提供的文件路径相关功能,只是一个命令行程序的话,就比较麻烦了。所以这一篇就来介绍Boost的filesystem库。 Boost的filesystem库主要包括了一些文件操作函数(复制、删除、读取文件属性等),一个path类(用于各种文件路径的变换),两个iterator(用于遍历目录)。

遍历文件目录

<!-- lang: cpp -->
#include <boost/filesystem.hpp>
namespace bfs=boost::filesystem;
template<typename WalkAction>  // 对目录中每一个文件和子目录的处理函数
bool walk(const bfs::path& inpath, WalkAction action, bool recursive)
{
	/* 判断传入的路径是不是一个有效的目录 */
	if (bfs::is_directory(inpath))
	{
		/* 是否遍历子目录 */
		if (recursive)
		{
			for(auto entry=bfs::recursive_directory_iterator(inpath);
				entry!=bfs::recursive_directory_iterator();++entry)
			{
				/* 遍历子目录,并对每一个文件和子目录调用action函数 */
				action(entry->path());
			}
		}
		else
		{
			for(auto entry=bfs::directory_iterator(inpath);
				entry!=bfs::directory_iterator();++entry)
			{
				/* 对当前目录下的每一个文件和子目录调用action函数 */
				action(entry->path());
			}
		}
		return true;
	}
	else
	{
		return false;
	}
}

新建目录

Boost的filesystem库本身是提供了新建目录的函数的,不过有一个不方便的地方,就是只能建一层目录,即要新建"/home/user/abc/def"的话,"/home/usre/abc"目录必须存在,所以我这里把filesystem的函数小小的封闭了一下。 <!-- lang: cpp --> void makedirs(const bfs::path& inpath) { /* 将传入路径转换成绝对路径 / / absolute()以外还有一个canonical()函数也是取绝对路径 / / canonical()会去掉路径中的".."和".",但是传入参数必须是一个真实有效的路径 / bfs::path fpath=bfs::absolute(inpath); / 检查要生成的路径是否已经存在 / if (!bfs::is_directory(inpath)) { bfs::path cur; / 如果fpath为"/home/user/abc/def",则fpath.begin()为"/home",fpath.begin()+1为"user" / for(auto item=fpath.begin();item!=fpath.end();++item) { / 连接路径 */ cur/=item; if(bfs::is_directory(cur)) { cur=bfs::canonical(cur); } else { / 新建目录 */ bfs::create_directory(cur); } } } }

在路径列表中查找指定文件

有时候需要检查某个软件是否已经安装了,而检测的最简单的方法就是看该软件的可执行文件是否存在。比如要检查JDK,只要看有没有javac就行了,至于到底是某公司还是社区提供的JDK其实并不重要。到哪里去找javac呢?因为安装路径可以任意指定,所以一般是在环境变量PATH指定的路径中去查找。 <!-- lang: cpp --> void findInPath(const std::string& filename, std::initializer_liststd::string additions, std::vectorbfs::path& result, int count) { /* 取得环境变量PATH的值 / std::string env(std::getenv("PATH")); #ifdef WIN32 const std::string sep(";"); #else const std::string sep(":"); #endif std::string::size_type pos1(0),pos2; std::vectorstd::string pathlist; / 优先查找指定目录,所以先把传入的路径加到列表里 / pathlist.reserve(additions.size()); std::copy(additions.begin(),additions.end(),std::back_inserter(pathlist)); / 分解环境变量PATH,并将路径加到列表里 / while(true) { pos2=env.find(sep,pos1); if (std::string::npos==pos2) { if (env.size()-pos1>0) { pathlist.push_back(env.substr(pos1)); } break; } else { if (pos2-pos1>0) { pathlist.push_back(env.substr(pos1,pos2-pos1)); } pos1=pos2+1; } } / 输出查找目录列表 / std::copy(pathlist.cbegin(),pathlist.cend(), std::ostream_iteratorstd::string(std::cout,"\n")); / 在列表中的每一个目录中查找目标文件 / for (auto &item:pathlist) { walk(bfs::path(item), / _saveToList函数将查找到的文件存入result中 */ std::bind(_saveToList,std::placeholders::_1,std::ref(result),filename), false); if ((count>0) && (result.size()-count>=0)) { break; } } } static void _saveToList(const bfs::path& file,std::vectorbfs::path& vec,const std::string& filename) { if (file.filename().generic_string()==filename) { vec.push_back(file); } }

创建一个临时文件

<!-- lang: cpp -->
/* 为临时文件新建一个目录 */
bfs::path tmpfile("temp/abc/def");
makedirs(tmpfile);
/* 生成一个唯一的文件名 */
tmpfile/=bfs::unique_path();
/* 写文件 */
std::ofstream ofs(tmpfile.generic_string());
ofs<<"test\n";
ofs.close();
/* 删除整个临时目录 */
bfs::remove_all("temp");
/* 其它文件操作:
 * copy, copy_directory, copy_file, copy_symlink
 *   copy会自动选择copy_directory/copy_file/copy_symlink中的一个
 * remove, remove_all
 *   remove用来删文件,remove_all用于删目录
 * rename
 */

完整的代码在demo-filesystem目录。

转载于:https://my.oschina.net/u/2002913/blog/311356

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值