程序设计:C++ UNIX/Linux 目录操作(源码)

UNIX/Linux上的目录操作。

几个功能:

  1. 判断是否是目录
  2. 创建路径
  3. 递归清理目录
  4. 递归处理目录的框架

代码不复杂,前三个就是函数(在同一个类中),最后一个是独立类,完整如下:

cpp 复制代码
#include --------------------//这里需要一些基础标准头文件
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>


	class CDir
	{
	public:
		static bool IsDir(char const * strPathName)
		{
			struct stat statBuf;

			if (stat(strPathName, &statBuf) == -1)
			{
				cout << "stat error : " << strPathName << endl;
				return false;
			}

			return(statBuf.st_mode & S_IFDIR);
		}
		static bool CreateDir(char const * filename)
		{
			string dirname;
			char const * p = filename;
			for (; '\0' != *p; ++p)
			{
				dirname += *p;
				if ('/' == *p)
				{
					//thelog<<dirname<<endi;
					mkdir(dirname.c_str(), S_IRWXU | S_IRWXG);
				}
			}
			return true;
		}
		static int ClearDir(char const * dirname, bool isKeepDir, long & count, long & count_err)
		{
			struct dirent *drip;
			DIR *dp;
			string fullname;
			string inputdir = dirname;
			if ((dp = opendir(inputdir.c_str())) == NULL)
			{
				++count_err;
				thelog << "Error open dir " << inputdir << " : " << strerror(errno) << ende;
				return __LINE__;
			}

			while ((drip = readdir(dp)) != NULL)
			{
				if (strcmp(drip->d_name, ".") == 0 || strcmp(drip->d_name, "..") == 0)
					continue;

				fullname = inputdir + "/" + drip->d_name;
				//thelog<<fullname<<endi;
				if (IsDir(fullname.c_str()))
				{
					ClearDir(fullname.c_str(), isKeepDir, count, count_err);
				}
				if (!isKeepDir || !IsDir(fullname.c_str()))
				{
					if (0 == unlink(fullname.c_str()))++count;
					else ++count_err;
				}

				if (count + count_err > 0 && 0 == (count + count_err) % 10000)
				{
					cout << "已处理 " << count + count_err << " 删除 " << count << " 个,出错 " << count_err << " 个" << endl;
				}
			}
			closedir(dp);

			return 0;
		}
	};
	class CForEachDir
	{
	private:
		//默认动作的数据
		int model;//内置的动作,0为显示名称
		long more_skip;//只处理这么多
		long doOneFile_count;//doOneFile用的计数
	private://接口
		//进入目录时调用一次
		virtual int doDirBegin(char const * dirname, long deep) { return 0; }
		virtual int doDirEnd(char const * dirname, long deep) { return 0; }
		//对每个文件调用一次
		virtual int doOneFile(char const * filename, bool isDir, long deep)
		{
			if (0 == model)
			{
				if (doOneFile_count < more_skip)cout << filename << endl;
				++doOneFile_count;
			}
			else
			{
				cout << "未知的模式 " << model << endl;
			}
			return 0;
		}
	private://内部函数
		int _doForEachDir(char const * dirname, bool isNoDir, bool r, long & count, long & count_err, long & _, long deep)
		{
			struct dirent *drip;
			DIR *dp;
			string fullname;
			string inputdir = dirname;
			if ((dp = opendir(inputdir.c_str())) == NULL)
			{
				++count_err;
				DEBUG_LOG << "Error open dir " << inputdir << " : " << strerror(errno) << ende;
				return __LINE__;
			}

			doDirBegin(inputdir.c_str(), deep);
			while ((drip = readdir(dp)) != NULL)
			{
				if (strcmp(drip->d_name, ".") == 0 || strcmp(drip->d_name, "..") == 0)
					continue;

				fullname = inputdir + "/" + drip->d_name;
				//thelog<<fullname<<endi;
				bool isdir = CDir::IsDir(fullname.c_str());
				if (isdir && r)
				{
					_doForEachDir(fullname.c_str(), isNoDir, r, count, count_err, _, deep + 1);
				}
				if (!isNoDir || !isdir)
				{
					if (0 == doOneFile(fullname.c_str(), isdir, deep))++count;
					else ++count_err;
				}

				if (_ != count + count_err)
				{
					_ = count + count_err;
					if (count + count_err > 0 && 0 == (count + count_err) % 10000)
					{
						cout << "已处理 " << count + count_err << " 成功 " << count << " 个,出错 " << count_err << " 个" << endl;
					}
				}
			}
			doDirEnd(inputdir.c_str(), deep);
			closedir(dp);

			return 0;
		}
	public:
		CForEachDir():model(-1){}
		int doForEachDir(char const * dirname, bool isNoDir, bool r, long & count, long & count_err)
		{
			count = 0;
			count_err = 0;
			long tmp = 0;
			return _doForEachDir(dirname, isNoDir, r, count, count_err, tmp, 0);
		}
		int showAllFileName(char const * dirname, long _more_skip = -1)
		{
			long count;
			long count_err;

			model = 0;
			more_skip = _more_skip;
			doOneFile_count = 0;
			return doForEachDir(dirname, true, true, count, count_err);
		}
	};

其中"thelog DEBUG_LOG endi"用来输出日志,替换为"cout endl"即可。

有问题问我。

(这里是结束)

相关推荐
小林熬夜学编程21 分钟前
【Linux系统编程】第五十弹---构建高效单例模式线程池、详解线程安全与可重入性、解析死锁与避免策略,以及STL与智能指针的线程安全性探究
linux·运维·服务器·c语言·c++·安全·单例模式
玖玖玖 柒染22 分钟前
windows下sqlplus连接到linux oracle不成功
linux·windows·oracle
LuckyTHP23 分钟前
CentOS 9 无法启动急救方法
linux·运维·centos
Bonne journée24 分钟前
centos和ubuntu有什么区别?
linux·ubuntu·centos
vvw&25 分钟前
如何在 Ubuntu 22.04 上安装带有 Nginx 的 ELK Stack
linux·运维·nginx·ubuntu·elk·elasticsearch·开源项目
Linux运维老纪27 分钟前
交换机配置从IP(Switch Configuration from IP)
linux·服务器·网络·安全·运维开发·ip
OneSea28 分钟前
Debian源码管理
linux
加载中loading...31 分钟前
C/C++实现tcp客户端和服务端的实现(从零开始写自己的高性能服务器)
linux·运维·服务器·c语言·网络
大筒木老辈子33 分钟前
Linux笔记---进程:初识进程
linux·服务器·笔记
木木em哈哈38 分钟前
archlinux安装waydroid
linux·运维·服务器