Windows程序设计第二版中多功能文件搜索器?

hyz23je 2011-11-28 03:53:59

CRapidFinder::CRapidFinder(int nMaxThread) : m_nMaxThread(nMaxThread)
{
m_nResultCount = 0;
m_nThreadCount = 0;
m_szMatchName[0] = '\0';

m_listDir.Construct(offsetof(CDirectoryNode, pNext));
m_hDirEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
::InitializeCriticalSection(&m_cs);
}

CRapidFinder::~CRapidFinder()
{
::CloseHandle(m_hDirEvent);
::CloseHandle(m_hExitEvent);
::DeleteCriticalSection(&m_cs);
}

BOOL CRapidFinder::CheckFile(LPCTSTR lpszFileName)
{
char string[MAX_PATH];
char strSearch[MAX_PATH];
strcpy(string, lpszFileName);
strcpy(strSearch, m_szMatchName);

// 将字符串string和strSearch中的字符全部转化成大写
_strupr(string);
_strupr(strSearch);

// 找出字符串strSearch在字符串string中第一次出现的位置
// 如果string中不包含strSearch,strstr函数返回NULL
if(strstr(string, strSearch) != NULL)
return TRUE;

return FALSE;
}


UINT FinderEntry(LPVOID lpParam)
{
CRapidFinder* pFinder = (CRapidFinder*)lpParam;
CDirectoryNode* pNode = NULL; // 从m_listDir中取出的节点
BOOL bActive = TRUE; // 指示当前线程的状态

// 循环处理m_listDir列表中的目录
while(1)
{
// 从m_listDir列表中取出一个新的目录
::EnterCriticalSection(&pFinder->m_cs);
if(pFinder->m_listDir.IsEmpty())
{
bActive = FALSE;
}
else
{
pNode = pFinder->m_listDir.GetHead();
pFinder->m_listDir.Remove(pNode);
}
::LeaveCriticalSection(&pFinder->m_cs);

// m_listDir为空的话就试图在m_hDirEvent事件上等待
if(!bActive)
{
// 准备进入等待状态
::EnterCriticalSection(&pFinder->m_cs);
pFinder->m_nThreadCount--;
if(pFinder->m_nThreadCount == 0) // 查看是否已经查找完毕
{
::LeaveCriticalSection(&pFinder->m_cs);
break;
}
::LeaveCriticalSection(&pFinder->m_cs);

// 进入等待状态
ResetEvent(pFinder->m_hDirEvent);
::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE);

// 变成活动线程后进入下一次循环
::EnterCriticalSection(&pFinder->m_cs);
pFinder->m_nThreadCount++;
::LeaveCriticalSection(&pFinder->m_cs);
bActive = TRUE;
continue;
}


// 在pNode指向的目录中查找文件

WIN32_FIND_DATA fileData;
HANDLE hFindFile;
// 设置成X:\XXXX\*.*的格式
if(pNode->szDir[strlen(pNode->szDir)-1] != '\\')
strcat(pNode->szDir, "\\");
strcat(pNode->szDir, "*.*");
hFindFile = ::FindFirstFile(pNode->szDir, &fileData);
if(hFindFile != INVALID_HANDLE_VALUE)
{
do
{
if(fileData.cFileName[0] == '.')
continue;
if(fileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
// 将搜索到的目录添加到目录列表中

// 为新的节点申请内存空间,设置完整的目录名称
CDirectoryNode* p = new CDirectoryNode;
strncpy(p->szDir, pNode->szDir, strlen(pNode->szDir)-3);
strcat(p->szDir, fileData.cFileName);
// 添加到列表中
::EnterCriticalSection(&pFinder->m_cs);
pFinder->m_listDir.AddHead(p);
::LeaveCriticalSection(&pFinder->m_cs);
// 促使一个“非活动线程”变成“活动线程”
::SetEvent(pFinder->m_hDirEvent); //???????????????????????
}
else
{
// 检查搜索到的文件
if(pFinder->CheckFile(fileData.cFileName))
{
::EnterCriticalSection(&pFinder->m_cs);
::InterlockedIncrement((long*)&pFinder->m_nResultCount);
::LeaveCriticalSection(&pFinder->m_cs);
printf(" %s \n", fileData.cFileName);
}
}
}while(::FindNextFile(hFindFile, &fileData));
}

// 此节点保存的目录已经搜索完毕,释放内存空间,进入下次循环
delete pNode;
pNode = NULL;
}

// 促使一个搜索线程从WaitForSingleObject函数返回,并退出循环
::SetEvent(pFinder->m_hDirEvent);

// 判断此线程是否是最后一个结束循环的线程,如果是就通知主线程
if(::WaitForSingleObject(pFinder->m_hDirEvent, 0) != WAIT_TIMEOUT)
// 如果此时pFinder->m_hDirEvent所对应的事件对象为受信状态,
// WaitForSingleObject函数的返回值将是WAIT_OBJECT_0
{
// 通知主线程最后一个搜索线程即将退出,文件搜索完毕
::SetEvent(pFinder->m_hExitEvent);

}
return 0;
}

问题一
::SetEvent(pFinder->m_hDirEvent); //是设置成为受信,但不明白它设置对应的是那个WaitForSingleObject呢?

if(pNode->szDir[strlen(pNode->szDir)-1] != '\\') //这里的判断为什么会是假的?里面减1有意义何在?
strcat(pNode->szDir, "\\");


strncpy(p->szDir, pNode->szDir, strlen(pNode->szDir)-3); //里面为什么要减3呢

就这三个问题!那位朋友帮忙解释下!




...全文
97 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hyz23je 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 visualeleven 的回复:]
1. 看你的传递给线程的那个结构体变量里的EVENT成员是哪个
[/Quote]

不太明白!
hyz23je 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 oyljerry 的回复:]
1. 查对应的event哪个在wait
2,减一获取字符串最后一个字符,然后判断是否为\结尾
[/Quote]

查过了!有两个!所以不知道它在哪一个上?
你回答的“减一获取字符串最后一个字符,然后判断是否为\结尾
”能再解释清楚一点吗?
Eleven 2011-11-28
  • 打赏
  • 举报
回复
后面两个Debug下调试一下看看具体的数据就知道为什么了
Eleven 2011-11-28
  • 打赏
  • 举报
回复
1. 看你的传递给线程的那个结构体变量里的EVENT成员是哪个
oyljerry 2011-11-28
  • 打赏
  • 举报
回复
1. 查对应的event哪个在wait
2,减一获取字符串最后一个字符,然后判断是否为\结尾
hyz23je 2011-11-28
  • 打赏
  • 举报
回复
自己顶个!
CRapidFinder::CRapidFinder(int nMaxThread) : m_nMaxThread(nMaxThread)
{
m_nResultCount = 0;
m_nThreadCount = 0;
m_szMatchName[0] = '\0';

m_listDir.Construct(offsetof(CDirectoryNode, pNext));
m_hDirEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
::InitializeCriticalSection(&m_cs);
}

CRapidFinder::~CRapidFinder()
{
::CloseHandle(m_hDirEvent);
::CloseHandle(m_hExitEvent);
::DeleteCriticalSection(&m_cs);
}

BOOL CRapidFinder::CheckFile(LPCTSTR lpszFileName)
{
char string[MAX_PATH];
char strSearch[MAX_PATH];
strcpy(string, lpszFileName);
strcpy(strSearch, m_szMatchName);

// 将字符串string和strSearch中的字符全部转化成大写
_strupr(string);
_strupr(strSearch);

// 找出字符串strSearch在字符串string中第一次出现的位置
// 如果string中不包含strSearch,strstr函数返回NULL
if(strstr(string, strSearch) != NULL)
return TRUE;

return FALSE;
}


UINT FinderEntry(LPVOID lpParam)
{
CRapidFinder* pFinder = (CRapidFinder*)lpParam;
CDirectoryNode* pNode = NULL; // 从m_listDir中取出的节点
BOOL bActive = TRUE; // 指示当前线程的状态

// 循环处理m_listDir列表中的目录
while(1)
{
// 从m_listDir列表中取出一个新的目录
::EnterCriticalSection(&pFinder->m_cs);
if(pFinder->m_listDir.IsEmpty())
{
bActive = FALSE;
}
else
{
pNode = pFinder->m_listDir.GetHead();
pFinder->m_listDir.Remove(pNode);
}
::LeaveCriticalSection(&pFinder->m_cs);

// m_listDir为空的话就试图在m_hDirEvent事件上等待
if(!bActive)
{
// 准备进入等待状态
::EnterCriticalSection(&pFinder->m_cs);
pFinder->m_nThreadCount--;
if(pFinder->m_nThreadCount == 0) // 查看是否已经查找完毕
{
::LeaveCriticalSection(&pFinder->m_cs);
break;
}
::LeaveCriticalSection(&pFinder->m_cs);

// 进入等待状态
ResetEvent(pFinder->m_hDirEvent);
::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE);

// 变成活动线程后进入下一次循环
::EnterCriticalSection(&pFinder->m_cs);
pFinder->m_nThreadCount++;
::LeaveCriticalSection(&pFinder->m_cs);
bActive = TRUE;
continue;
}


// 在pNode指向的目录中查找文件

WIN32_FIND_DATA fileData;
HANDLE hFindFile;
// 设置成X:\XXXX\*.*的格式
if(pNode->szDir[strlen(pNode->szDir)-1] != '\\') //????????
strcat(pNode->szDir, "\\");
strcat(pNode->szDir, "*.*");
hFindFile = ::FindFirstFile(pNode->szDir, &fileData);
if(hFindFile != INVALID_HANDLE_VALUE)
{
do
{
if(fileData.cFileName[0] == '.')
continue;
if(fileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
// 将搜索到的目录添加到目录列表中

// 为新的节点申请内存空间,设置完整的目录名称
CDirectoryNode* p = new CDirectoryNode;
strncpy(p->szDir, pNode->szDir, strlen(pNode->szDir)-3); //???????
strcat(p->szDir, fileData.cFileName);
// 添加到列表中
::EnterCriticalSection(&pFinder->m_cs);
pFinder->m_listDir.AddHead(p);
::LeaveCriticalSection(&pFinder->m_cs);
// 促使一个“非活动线程”变成“活动线程”
::SetEvent(pFinder->m_hDirEvent); //???????????????????????
}
else
{
// 检查搜索到的文件
if(pFinder->CheckFile(fileData.cFileName))
{
::EnterCriticalSection(&pFinder->m_cs);
::InterlockedIncrement((long*)&pFinder->m_nResultCount);
::LeaveCriticalSection(&pFinder->m_cs);
printf(" %s \n", fileData.cFileName);
}
}
}while(::FindNextFile(hFindFile, &fileData));
}

// 此节点保存的目录已经搜索完毕,释放内存空间,进入下次循环
delete pNode;
pNode = NULL;
}

// 促使一个搜索线程从WaitForSingleObject函数返回,并退出循环
::SetEvent(pFinder->m_hDirEvent);

// 判断此线程是否是最后一个结束循环的线程,如果是就通知主线程
if(::WaitForSingleObject(pFinder->m_hDirEvent, 0) != WAIT_TIMEOUT)
// 如果此时pFinder->m_hDirEvent所对应的事件对象为受信状态,
// WaitForSingleObject函数的返回值将是WAIT_OBJECT_0
{
// 通知主线程最后一个搜索线程即将退出,文件搜索完毕
::SetEvent(pFinder->m_hExitEvent);
}
return 0;
}

【更新至2025年】2001-2025年上市公司数字化转型年报词频统计(吴非、赵宸宇、甄红线)(300+年报词频统计) 1、时间:2001-2025年 2、来源:上市公司年报 3、参考文献:企业数字化转型与资本市场表现——来自股票流动性的经验证据(吴非) 数字化转型如何影响企业全要素生产率(赵宸宇) 知识产权行政保护与企业数字化转型(甄红线) 4、方法说明:(1)参考吴非老师的做法,对人工智能技术、大数据技术、云计算技术、区块链技术、数字技术运用五个维度76个数字化相关词频进行统计 (2)参考赵宸宇老师的做法,对数字技术应用、互联网商业模式、智能制造、现代信息系统四个维度99个数字化相关词频进行统计 (3)参考甄红线老师的做法,对技术分类、组织赋能、数字化应用等类别下139个数字化相关词频进行统计 5、指标:年份、股票代码、公司简称、行业名称、行业代码、全文-文本总长度、仅英文-文本总长度、人工智能技术-吴、大数据技术-吴、云计算技术-吴、区块链技术-吴、数字技术运用-吴、数字技术应用-赵、互联网商业模式-赵、智能制造-赵、现代信息系统-赵、技术分类-人工智能技术-甄、技术分类-区块链技术-甄、技术分类-云计算技术-甄、技术分类-大数据技术-甄、组织赋能-人工智能技术-甄、组织赋能-云计算技术-甄、组织赋能-大数据技术-甄、组织赋能-广义数字技术-甄、数字化应用-技术创新-甄、数字化应用-流程创新-甄、数字化应用-业务创新-甄、人工智能、商业智能、图像理解、投资决策辅助系统、智能数据分析、智能机器人、机器学习、深度学习、语义搜索、生物识别技术、人脸识别、语音识别、身份验证、自动驾驶、自然语言处理、大数据、数据挖掘、文本挖掘、数据可视化、异构数据、征信、增强现实、混合现实、虚拟现实、云计算、流计算、图计算、内存计算、多方安全计算、类脑计算、绿色计算、认知计算等300+词频

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧