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

有问题问我。

(这里是结束)

相关推荐
矛取矛求2 小时前
Linux如何更优质调节系统性能
linux
李元豪3 小时前
【智鹿空间】c++实现了一个简单的链表数据结构 MyList,其中包含基本的 Get 和 Modify 操作,
数据结构·c++·链表
UestcXiye3 小时前
《TCP/IP网络编程》学习笔记 | Chapter 9:套接字的多种可选项
c++·计算机网络·ip·tcp
内核程序员kevin3 小时前
在Linux环境下使用Docker打包和发布.NET程序并配合MySQL部署
linux·mysql·docker·.net
kayotin4 小时前
Wordpress博客配置2024
linux·mysql·docker
一丝晨光4 小时前
编译器、IDE对C/C++新标准的支持
c语言·开发语言·c++·ide·msvc·visual studio·gcc
丶Darling.4 小时前
Day40 | 动态规划 :完全背包应用 组合总和IV(类比爬楼梯)
c++·算法·动态规划·记忆化搜索·回溯
Ztiddler4 小时前
【Linux Shell命令-不定期更新】
linux·运维·服务器·ssh
小小不董5 小时前
Oracle OCP认证考试考点详解082系列16
linux·运维·服务器·数据库·oracle·dba
奶味少女酱~5 小时前
常用的c++特性-->day02
开发语言·c++·算法