作者:朱金灿

来源:http://blog.csdn.net/clever101

这里说的除虫是指排除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;
}

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

除虫记——有关WindowsAPI文件查找函数的一次压力测试的更多相关文章

  1. 除虫记之C#调用C函数出现的诡异错误

     作者:朱金灿 来源:http://blog.csdn.net/clever101 同事反映在在项目中使用C#程序调用我们部门编写的C++模块出现一个诡异错误:在调用A算法失败后,其它算法均不能调 ...

  2. 记在VMware虚拟机中对网站进行性能压力测试的经历

    由于本次测试,仅仅是对静态网站首页进行的测试,所以没有涉及到MySQL数据库的性能监测 服务器基本配置 webbench测试工具 Linux上一款优秀的web性能压力测试工具.webbench最多可以 ...

  3. C 语言函数手册:涵盖字符测试、字符串操作、内存管理、时间换算、数学计算、文件操作、进程管理、文件权限控制、信号处理、接口处理、环境变量、终端控制

    1. 字符测试函数 函数 说明 isascii() 判断字符是否为ASCII码字符 2. 字符串操作 函数 说明 gcvt() 将浮点型数转换为字符串(四舍五入) index() 查找字符串并返回首次 ...

  4. EPANET中读取INPUT文件的函数文件——INPUT1.C/INPUT2.C/INPUT3.C

    首先介绍下这3个文件的关系:可以说INPUT1.C的函数粒度最大,它的函数getdata()就完成了整个INPUT文件数据的读入,该函数又调用了INPUT2.C中的部分函数,INPUT2.C文件中的函 ...

  5. string.h文件中函数用法

    下面为string.h文件中函数的详细用法: strcpy函数名:strcpy功 能: 拷贝一个字符串到另一个用 法: char *strcpy(char *destin, char *source) ...

  6. 捉虫记(四)线程安全导致的HighCpu

    一个朋友QQ群里说网站启动后会cpu很高,想要帮忙看一下dump. 1.打开windbg加载dump文件后第一个命令lmf,这个命令显示加载的dll以及路径,这样子可以找个dll来帮忙加载sos,(额 ...

  7. C/C++常用头文件及函数汇总

    转自: C/C++常用头文件及函数汇总 C/C++头文件一览 C #include <assert.h> //设定插入点#include <ctype.h> //字符处理#in ...

  8. VS2005(vs2008,vs2010)使用map文件查找程序崩溃原因

    VS 2005使用map文件查找程序崩溃原因 一般程序崩溃可以通过debug,找到程序在那一行代码崩溃了,最近编一个多线程的程序,都不知道在那发生错误,多线程并发,又不好单行调试,终于找到一个比较好的 ...

  9. C语言常用的库文件(头文件、函数库)

    C语言常用的库文件(头文件.函数库) C系统提供了丰富的系统文件,称为库文件.C的库文件分为两类,一类是扩展名为".h"的文件,称为头文件,在前面的包含命令中我们已多次使用过.在& ...

随机推荐

  1. .NETFramework:Thread

    ylbtech-.NETFramework:Thread 1.返回顶部 1. #region 程序集 mscorlib, Version=2.0.0.0, Culture=neutral, Publi ...

  2. bzoj2806

    广义后缀自动机+二分+单调队列+dp 这道题其实就是一个简单dp,dp[i]表示匹配到i最长匹配多少,设val[i]表示当前位置和原串的最长公共长度,二分的长度是L,那么要求dp[i]=max(dp[ ...

  3. 网页中控制ActiveX插件高度

    说明:IE窗口中承载了一个ActiveX插件,试图使该插件充填窗口(自适应窗口的高度.宽度),且不出滚动条. 承载插件的代码如下: <body>    <form id=" ...

  4. A - Vasya and Socks

    A - Vasya and Socks Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64 ...

  5. 2.11-2.12 HBase的数据迁移常见方式

    一.importtsv 把hdfs中数据抽取到HBase表中: 1.准备数据 ##student.tsv [root@hadoop-senior datas]# cat student.tsv 100 ...

  6. Ubuntu下对与rtl8723be网卡频繁断网问题解决

    linux下对于rtl系列的无线网卡,大多数网友都在吐槽,总是频繁的掉网,就此将自己在网上安装时的经验写下. 1.下载网卡驱动,其中包含rtl的大多数包 sudo apt-get install li ...

  7. c# 调用 webservices (转载)

    .net 调用webservice 总结 最近做一个项目,由于是在别人框架里开发app,导致了很多限制,其中一个就是不能直接引用webservice . 我们都知道,调用webserivice 最简单 ...

  8. http协议之版本差异(2)

    —————————————HTTP1.0/HTTP1.1—————————————— 建立连接方面 HTTP/1.0 每次请求都需要建立新的TCP连接,连接不能复用.HTTP/1.1 新的请求可以在上 ...

  9. 5-2 Windows消息队列 (25分)

    5-2 Windows消息队列   (25分) 消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生,如点击鼠标.文字改变等,系统将把这个消息加到队列当中 ...

  10. poj2133(sg函数)

    关于sg函数:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561007.html 题目链接:http://poj.org/problem?id=2 ...