程序设计: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"即可。

有问题问我。

(这里是结束)

相关推荐
夕泠爱吃糖1 小时前
Linux 文件内容的查询与统计
android·linux·c#
love530love2 小时前
【笔记】NVIDIA AI Workbench 中安装 cuDNN 9.10.2
linux·人工智能·windows·笔记·python·深度学习
果子⌂2 小时前
PostgreSQL --数据库操作
linux·数据库·postgresql
SundayBear2 小时前
适合有C基础后快速上手C++
开发语言·c++
顾三殇2 小时前
【自考】《计算机信息管理课程实验(课程代码:11393)》华师自考实践考核题型解析说明:C++ 与 mysql 实践题型与工具实践题分析
c++·mysql·华师自考实践考核题型分析
newki2 小时前
【NDK】项目演示-Android串口的封装工具库以及集成的几种思路
android·c++·app
倔强的石头1062 小时前
【Linux指南】文件系统基础操作与路径管理
linux·运维·服务器
whoarethenext2 小时前
使用 C++ 和 OpenCV 构建智能答题卡识别系统
开发语言·c++·opencv
Epiphany.5562 小时前
堆排序code
数据结构·c++·算法
Dfreedom.3 小时前
Excel文件数据的读取和处理方法——C++
c++·数据分析·excel·数据预处理