博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
除虫记——有关WindowsAPI文件查找函数的一次压力测试
阅读量:2430 次
发布时间:2019-05-10

本文共 2623 字,大约阅读时间需要 8 分钟。

作者:朱金灿

来源:

 

        这里说的除虫是指排除bug的意思。今天排除了一个有意思的bug,其中的场景大致是这样的:现在你要统计一个文件夹下非隐藏文件的数目(包含它的子文件夹),很快你写出这样的代码:

//dirName ——文件夹路径//nImgNum ——文件数量bool StatFiles(std::string& dirName,int& nImgNum){	std::string tempFileFind = dirName + _T("\\*") ;	HANDLE hFind = INVALID_HANDLE_VALUE;	WIN32_FIND_DATA ffd;	hFind = FindFirstFile(tempFileFind.c_str(), &ffd);	if (hFind != INVALID_HANDLE_VALUE)	{		do		{			tString strSub = dirName + _T("\\") + ffd.cFileName;			if (((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0)				&&((ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)==0))			{                nImgNum++; 			}		}while (FindNextFile(hFind, &ffd) != 0);	}	else	{		return false;	}	tempFileFind = dirName + _T("\\*");	hFind = INVALID_HANDLE_VALUE;	hFind = FindFirstFile(tempFileFind.c_str(), &ffd);	if (hFind != INVALID_HANDLE_VALUE)	{		do		{			if (ffd.cFileName[0] == '.')			{				if (ffd.cFileName[1] == '\0' ||					(ffd.cFileName[1] == '.' &&					ffd.cFileName[2] == '\0'))				{					continue;				}			}			std::string strSub = dirName + _T("\\") + ffd.cFileName;			if (!((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0))			{				StatFiles(strSub,nImgNum);			}		}while (FindNextFile(hFind, &ffd) != 0);	}	return true;}

         然后拿一个文件夹来测试,嗯,测试没有问题,返回的数目也是对的。然后我们拿一个包含很多子文件夹和文件来测试,发现运行到文件数是七千多的时候函数就返回false了。开始我们比较迷惑,后来发现问题了,原来是忘记关闭文件查找句柄了,当统计达到七千多的时候已经把windows的查找句柄资源消耗尽了。我感觉这真是对WindowsAPI文件查找函数的一次压力测试。正确的代码应该是这样的:

//dirName ——文件夹路径//nImgNum ——文件数量bool StatFiles(std::string& dirName,int& nImgNum){	std::string tempFileFind = dirName + _T("\\*") ;	HANDLE hFind = INVALID_HANDLE_VALUE;	WIN32_FIND_DATA ffd;	hFind = FindFirstFile(tempFileFind.c_str(), &ffd);	if (hFind != INVALID_HANDLE_VALUE)	{		do		{			tString strSub = dirName + _T("\\") + ffd.cFileName;			if (((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0)				&&((ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)==0))			{                nImgNum++; 			}		}while (FindNextFile(hFind, &ffd) != 0);	}	else	{		return false;	}    FindClose(hFind); //记得关闭文件查找句柄	tempFileFind = dirName + _T("\\*");	hFind = INVALID_HANDLE_VALUE;	hFind = FindFirstFile(tempFileFind.c_str(), &ffd);	if (hFind != INVALID_HANDLE_VALUE)	{		do		{			if (ffd.cFileName[0] == '.')			{				if (ffd.cFileName[1] == '\0' ||					(ffd.cFileName[1] == '.' &&					ffd.cFileName[2] == '\0'))				{					continue;				}			}			std::string strSub = dirName + _T("\\") + ffd.cFileName;			if (!((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0))			{				StatFiles(strSub,nImgNum);			}		}while (FindNextFile(hFind, &ffd) != 0);	}    FindClose(hFind); //记得关闭文件查找句柄	return true;}

 

       如何避免这种资源泄漏的问题的发生?首先需要明确你要申请的是一种资源,在使用资源之前需要明确在哪儿释放掉资源从而避免资源泄漏。

转载地址:http://xdimb.baihongyu.com/

你可能感兴趣的文章
苹果公司揭秘首批列入 Swift 源代码兼容性开源项目清单
查看>>
Python 玩转物联网之 Micropython GPIO IRQ 处理
查看>>
移动周刊第 188 期:Android 安全性要点与规范核心详析
查看>>
手机为基础的 IoT 布局已经失效,下一代操作系统是什么模样?
查看>>
无线传感器网络使用指南
查看>>
Unity 脚本优化的那些坑
查看>>
《近匠》专访机智云 CTO 刘琰——从 0 到 1 开启智能化硬件开发
查看>>
深度对话微软,解读 HoloLens 技术设计细节
查看>>
移动周刊第 191 期:如何看待 Kotlin 成为 Android 官方支持开发语言?
查看>>
物联网浪潮之下,前端工程师如何迎刃而上?
查看>>
从端到云——工业物联网项目全栈快速开发
查看>>
LoRa vs NB-IOT:哪个物联网标准更具优势?
查看>>
移动周刊第 205 期:Google 正式发布 ARCore 预览版、iOS 工程打包速度提升十倍的解决方案...
查看>>
八大 IoT 安全关键技术解析
查看>>
有钱 Python,没钱 PHP,编程语言也嫌贫爱富
查看>>
Docker是啥?容器变革的火花?
查看>>
假如从餐饮店的角度来看架构…
查看>>
这个充电宝太黑科技了,又小又不用自己带线,长见识了~
查看>>
HDC.2019后再发力,AppGallery Connect服务新升级
查看>>
网易云音乐热评的规律,44万条数据告诉你
查看>>