VC++实现文件全盘搜索
很久没更新了,今天决定写点东西。
这是我以前写的一个C++的类,可以在硬盘上全盘搜索指定的文件(可以用通配符),还可以添加过滤器,以便搜索特定的文件。该类使用链表储存搜索结果(学了那么多数据结构,总算可以用一把了),性能还是可以的。虽说没什么技术含量,但也挺有用的
下面就是这个类的代码,包括测试程序,原本我没有写注释,现在加上了一些。
很久没更新了,今天决定写点东西。
这是我以前写的一个C++的类,可以在硬盘上全盘搜索指定的文件(可以用通配符),还可以添加过滤器,以便搜索特定的文件。该类使用链表储存搜索结果(学了那么多数据结构,总算可以用一把了),性能还是可以的。虽说没什么技术含量,但也挺有用的
下面就是这个类的代码,包括测试程序,原本我没有写注释,现在加上了一些。
这个博客居然不支持C++的代码插入,只好用C#的来将就一下了.
#include <windows.h>
#include <shlwapi.h>
#include <iostream>
#pragma comment(lib, "shlwapi.lib")
using namespace std;
//定义过滤器的最大数量
#define CONST_MAX_FILTER 16
//链表的数据结构
typedef struct tagList{
TCHAR szFile[MAX_PATH];
struct tagList *NextFile;
}FileList, *PFileList;
//主体类
class CHunter{
public:
CHunter();
~CHunter();
void AddFilter( TCHAR *szFilter ); //添加过滤器
void CHunter::Hunt( TCHAR *szPath );
TCHAR *GetFile(); //取得链表中的文件
DWORD GetFileCount(); //取得文件的数量
private:
PFileList headNode; //链表头
PFileList currNode;
void AddFile( TCHAR *szFile );
void HuntFile( char *lpPath ) ;
TCHAR szFilter[CONST_MAX_FILTER][5] ;
DWORD dwFilterCount ;
DWORD dwFileCount ;
};
CHunter::CHunter():dwFilterCount(0),dwFileCount(0)
{
headNode = (FileList *)malloc( sizeof(FileList) );
headNode->NextFile = NULL;
currNode = headNode;
for( int i=0; i< CONST_MAX_FILTER; i++)
ZeroMemory( szFilter[i], 5 ) ;
}
CHunter::~CHunter()
{
PFileList next, tmp;
tmp = headNode;
while( tmp->NextFile != NULL )
{
next = tmp->NextFile ;
free(tmp);
tmp = next;
}
free(tmp);
}
//添加过滤器,比如.txt,为了简省,没有考虑文件扩展名长度大于4的情况
//请自行修改
void CHunter::AddFilter( TCHAR *szInp )
{
if( strlen(szInp) > 4 )
return;
strncpy( szFilter[dwFilterCount++], szInp, 5 );
}
void CHunter::AddFile( TCHAR *szFile )
{
currNode->NextFile = (FileList *)malloc( sizeof(FileList) );
currNode = currNode->NextFile;
ZeroMemory(currNode->szFile, MAX_PATH );
currNode->NextFile = NULL ;
strncpy( currNode->szFile, szFile, MAX_PATH );
dwFileCount++;
}
//这是入口函数,调用它即可开始搜索,这个路径的尾部不应有反斜杠
void CHunter::Hunt( TCHAR *szPath )
{
HuntFile( szPath );
currNode = headNode->NextFile;
}
DWORD CHunter::GetFileCount()
{
return this->dwFileCount;
}
//这个函数依次遍历链表中的文件,并返回一个文件名
TCHAR *CHunter::GetFile()
{
TCHAR *szRet;
szRet = currNode->szFile;
currNode = currNode->NextFile;
return szRet;
}
void CHunter::HuntFile( char * lpPath)
{
char szFind[MAX_PATH];
char szFile[MAX_PATH];
WIN32_FIND_DATA FindFileData;
ZeroMemory(szFind,MAX_PATH);
ZeroMemory(szFile,MAX_PATH);
strcpy(szFind,lpPath);
strcat(szFind, "\\*.*");
HANDLE hFind=::FindFirstFile(szFind,&FindFileData);
if(INVALID_HANDLE_VALUE == hFind) return;
while(TRUE)
{
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(FindFileData.cFileName[0]!='.')
{
strcpy(szFile,lpPath);
strcat(szFile,"\\");
strcat(szFile,FindFileData.cFileName);
HuntFile(szFile);
}
}
else
{
strcpy(szFile,lpPath);
strcat(szFile,"\\");
strcat(szFile,FindFileData.cFileName);
//cout << szFile << FindFileData.cFileName << endl;
for( int i=0; i< dwFilterCount; i++ )
if( strncmp(szFilter[i], PathFindExtension(szFile), 5) == 0 )
this->AddFile( szFile );
}
if(!FindNextFile(hFind,&FindFileData)) break;
}
FindClose(hFind);
}
//示例,搜索D盘所有的exe文件
int main( int argc, char* argv[])
{
CHunter hunter;
hunter.AddFilter( ".exe");
hunter.Hunt( "D:");
cout<< hunter.GetFileCount() << endl;
for( int i=0; i< hunter.GetFileCount(); i++)
cout<< hunter.GetFile() << endl;
return 0;
}
#include <shlwapi.h>
#include <iostream>
#pragma comment(lib, "shlwapi.lib")
using namespace std;
//定义过滤器的最大数量
#define CONST_MAX_FILTER 16
//链表的数据结构
typedef struct tagList{
TCHAR szFile[MAX_PATH];
struct tagList *NextFile;
}FileList, *PFileList;
//主体类
class CHunter{
public:
CHunter();
~CHunter();
void AddFilter( TCHAR *szFilter ); //添加过滤器
void CHunter::Hunt( TCHAR *szPath );
TCHAR *GetFile(); //取得链表中的文件
DWORD GetFileCount(); //取得文件的数量
private:
PFileList headNode; //链表头
PFileList currNode;
void AddFile( TCHAR *szFile );
void HuntFile( char *lpPath ) ;
TCHAR szFilter[CONST_MAX_FILTER][5] ;
DWORD dwFilterCount ;
DWORD dwFileCount ;
};
CHunter::CHunter():dwFilterCount(0),dwFileCount(0)
{
headNode = (FileList *)malloc( sizeof(FileList) );
headNode->NextFile = NULL;
currNode = headNode;
for( int i=0; i< CONST_MAX_FILTER; i++)
ZeroMemory( szFilter[i], 5 ) ;
}
CHunter::~CHunter()
{
PFileList next, tmp;
tmp = headNode;
while( tmp->NextFile != NULL )
{
next = tmp->NextFile ;
free(tmp);
tmp = next;
}
free(tmp);
}
//添加过滤器,比如.txt,为了简省,没有考虑文件扩展名长度大于4的情况
//请自行修改
void CHunter::AddFilter( TCHAR *szInp )
{
if( strlen(szInp) > 4 )
return;
strncpy( szFilter[dwFilterCount++], szInp, 5 );
}
void CHunter::AddFile( TCHAR *szFile )
{
currNode->NextFile = (FileList *)malloc( sizeof(FileList) );
currNode = currNode->NextFile;
ZeroMemory(currNode->szFile, MAX_PATH );
currNode->NextFile = NULL ;
strncpy( currNode->szFile, szFile, MAX_PATH );
dwFileCount++;
}
//这是入口函数,调用它即可开始搜索,这个路径的尾部不应有反斜杠
void CHunter::Hunt( TCHAR *szPath )
{
HuntFile( szPath );
currNode = headNode->NextFile;
}
DWORD CHunter::GetFileCount()
{
return this->dwFileCount;
}
//这个函数依次遍历链表中的文件,并返回一个文件名
TCHAR *CHunter::GetFile()
{
TCHAR *szRet;
szRet = currNode->szFile;
currNode = currNode->NextFile;
return szRet;
}
void CHunter::HuntFile( char * lpPath)
{
char szFind[MAX_PATH];
char szFile[MAX_PATH];
WIN32_FIND_DATA FindFileData;
ZeroMemory(szFind,MAX_PATH);
ZeroMemory(szFile,MAX_PATH);
strcpy(szFind,lpPath);
strcat(szFind, "\\*.*");
HANDLE hFind=::FindFirstFile(szFind,&FindFileData);
if(INVALID_HANDLE_VALUE == hFind) return;
while(TRUE)
{
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(FindFileData.cFileName[0]!='.')
{
strcpy(szFile,lpPath);
strcat(szFile,"\\");
strcat(szFile,FindFileData.cFileName);
HuntFile(szFile);
}
}
else
{
strcpy(szFile,lpPath);
strcat(szFile,"\\");
strcat(szFile,FindFileData.cFileName);
//cout << szFile << FindFileData.cFileName << endl;
for( int i=0; i< dwFilterCount; i++ )
if( strncmp(szFilter[i], PathFindExtension(szFile), 5) == 0 )
this->AddFile( szFile );
}
if(!FindNextFile(hFind,&FindFileData)) break;
}
FindClose(hFind);
}
//示例,搜索D盘所有的exe文件
int main( int argc, char* argv[])
{
CHunter hunter;
hunter.AddFilter( ".exe");
hunter.Hunt( "D:");
cout<< hunter.GetFileCount() << endl;
for( int i=0; i< hunter.GetFileCount(); i++)
cout<< hunter.GetFile() << endl;
return 0;
}
本文转自 kevx 51CTO博客,原文链接:http://blog.51cto.com/spinlock/170515,如需转载请自行联系原作者