C++ Boost( 2 )-filesystem 实现一个的rmdir

上一篇博客已经介绍了boost库,那现在就直接上强度!

先来讲解一下思路:

fs::remove_all()不能保证删除干净,它会在第一次发生错误时退出。

因此用remove+directory_interator类遍历目录。

第二个问题是错误处理

,try的效率低而且无法加工错误信息,因此这里用error_code。

bool Remove(fs::path rmPath) {
	boost::system::error_code errorCode;
	bool isDir = fs::is_directory(rmPath, errorCode);
	if (errorCode)
		PutError(rmPath.string() + " - " + errorCode.message());
	if (isDir) {
		fs::directory_iterator dirIterator(rmPath, errorCode);
		if (errorCode)
			PutError(rmPath.string() + " - " + errorCode.message());
		for (fs::directory_entry entry : dirIterator) {
			fs::path path(entry.path());
			bool isDir = fs::is_directory(path, errorCode);
			if (errorCode)
				PutError(path.string() + " - " + errorCode.message());
			if (isDir) {
				if (mode_s)
					Remove(path);
			} else
				Remove(path);
		}
		fs::remove(rmPath, errorCode);
		if (errorCode)
			return PutError(rmPath.string() + " - " + errorCode.message()), false;
		else
			return PutMessage("已删除文件夹:" + rmPath.string()), true;
	} else {
		fs::remove(rmPath, errorCode);
		if (errorCode)
			return PutError(rmPath.string() + " - " + errorCode.message()), false;
		else
			return PutMessage("已删除文件:  " + rmPath.string()), true;
	}
}

这是主体代码,Remove()函数。

error_code.message()只返回“拒绝访问”这种简短的报告,不像catch那样粗鲁:

boost::filesystem::remove()::拒绝访问,那岂不暴露是boost了吗?

Remove函数就这样递归删除,return true表示删干净了,否则就有错误。

接下来是完整代码

/**
 * @file rmdir.cpp
 * @brief 递归删除文件和目录的工具
 * @author Liu-Yuze
 * @date 2025
 * @license Boost Software License 1.0
 */

#include <boost/filesystem.hpp>
#include <iostream>
#include <vector>

namespace fs = boost::filesystem;

int Options = 0;
enum Option {
	RECURSIVE = 0x1,
	QUIET = 0x2,
	SUPPRESS_ERROR = 0x4,
};

void PutError(const std::string& errorMessage) {
	if (!(Options & SUPPRESS_ERROR))
		std::cerr << errorMessage << '\n';
}

void PutMessage(const std::string& message) {
	if (!(Options & QUIET))
		std::cout << message << '\n';
}

//主函数,可以删除目录和文件,返回0则没删干净。
bool Remove(fs::path rmPath) {
	//error_code一个就够。
	boost::system::error_code errorCode;
	bool isDir = fs::is_directory(rmPath, errorCode);
	if (errorCode)
		PutError(rmPath.string() + " - " + errorCode.message());
	//如果是文件夹,递归删除子文件夹和文件,再删除自己。
	if (isDir) {
		//文件夹迭代器,解析文件夹内容。
		fs::directory_iterator dirIterator(rmPath, errorCode);
		if (errorCode)
			PutError(rmPath.string() + " - " + errorCode.message());
		//遍历子文件夹和文件。
		for (fs::directory_entry entry : dirIterator) {
			fs::path path(entry.path());
			bool isDir = fs::is_directory(path, errorCode);
			if (errorCode)
				PutError(path.string() + " - " + errorCode.message());
			//是文件夹而且递归删除模式开启。
			if (isDir) {
				if (Options & RECURSIVE)
					Remove(path);
			}
			//是文件直接删。
			else
				Remove(path);
		}
		//这是删除文件部分,删掉了就返回true,否则就是文件夹里有文件。
		fs::remove(rmPath, errorCode);
		if (errorCode)
			return PutError(rmPath.string() + " - " + errorCode.message()), false;
		else
			return PutMessage("已删除文件夹:" + rmPath.string()), true;
	}
	else {
		//这是删除文件部分,删掉了就返回true.
		fs::remove(rmPath, errorCode);
		if (errorCode)
			return PutError(rmPath.string() + " - " + errorCode.message()), false;
		else
			return PutMessage("已删除文件:  " + rmPath.string()), true;
	}
}

void ShowHelp() {
	PutMessage(
		"Usage: rmdir [Options] <path1> <path2> ...\n"
		"Options:\n"
		"  -recursive          递归删除目录\n"
		"  -quiet              抑制删除信息\n"
		"  --suppress-errors   抑制错误信息\n"
		"  --help/-?           显示帮助信息"
	);
}

int main(int argc, char* argv[]) {
	try {//std的函数有点多,以防万一吧!
		//没有用到cstdio,那stdio就牺牲一下吧!
		std::ios::sync_with_stdio(false);
		boost::system::error_code error_code;
		//至少要个运行路径和删除目录吧。
		if (argc < 2) {
			PutError("Usage: rmdir [Options] <path1> <path2> ...");
			return 0;
		}
		//要删除的目录在这里。
		std::vector<fs::path> pathToRemove;
		for (int i = 1; i < argc; ++i) {
			try {
				std::string arg = argv[i];
				//fs::absolute(fs::path)函数是处理斜杠的。
				fs::path path = fs::absolute(arg, error_code);
				if (error_code)
					PutError(arg + " - " + error_code.message());
				//判断路径存不存在,存在就把完整路径丢给pathToRemove的构造函数,
				//也就是fs::canonical(fs::path)函数,它会处理"./../"之类的。
				if (fs::exists(path)) {
					pathToRemove.emplace_back(fs::canonical(path, error_code));
					if (error_code)
						PutError(error_code.message());
				}
				//不知道的看ShowHelp()函数。
				else if (arg == "--help" || arg == "-?") {
					ShowHelp();
					return 0;
				}
				else if (arg == "-recursive")
					Options |= RECURSIVE;
				else if (arg == "-quiet")
					Options |= QUIET;
				else if (arg == "--suppress-errors")
					Options |= SUPPRESS_ERROR;
				else
					PutError("没有路径或选项:" + arg);

			}
			catch (const fs::filesystem_error& e) {
				PutError(e.what());
			}
		}
		//一堆选项却没路径。
		if (pathToRemove.empty()) {
			PutError("请指定有效路径!");
			return 2;
		}
		bool isRemove = true;
		for (const auto& path : pathToRemove)
			isRemove &= Remove(path);
		//删干净了返回0,否则返回1。
		return (isRemove) ? 0 : 1;
	}
	catch (std::exception& e) {
		PutError(e.what());
		return 3;
	}
}

一个简单的rmdir就是这么简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值