📄 filefindext.cpp
字号:
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// FileFindExt.cpp: implementation of the CFileFindExt class.
/********************************************************************/
/* *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--* */
/* | 中国科学院计算技术研究所 | */
/* *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--* */
/* 编程环境: Visual C++ 6.0 (Windows 2000) */
/* 作 者: 唐 胜 */
/* 邮 箱: ts@ict.ac.cn */
/* 发布版本: V1.2.1 */
/* 发布日期: Nov. 01, 2003 */
/* 功能说明:搜索同一目录下的所有同类型文件,并进行处理 */
/* 版本修改: */
/* V1.0:Sep. 26, 2002, 递归实现 */
/* V1.1:Oct. 20, 2003, 为加快搜索速度,减少开销 */
/* 采用先深遍历非递归化实现 */
/* V1.2:Oct. 21, 2003, 考虑目录的层次结构,采用 */
/* 广度遍历非递归化实现,并直接做成类 */
/* v1.2.1: Nov. 01, 2003 对V1.2进行了优化 */
/* 说 明:今后根据需要可增加其它多参数处理函数,或修改处 */
/* 理函数, 使用时请保留以上相关信息 */
/********************************************************************/
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FileFindExt.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//构造函数和析构函数
/************************************************************************
功能说明: CFileFindExt的构造函数
参数说明: 无
输出说明: 无
函数调用: 类CStringArray的SetSize()和RemoveAll()
*************************************************************************/
CFileFindExt::CFileFindExt()
{
m_FileNames.SetSize(MAX_PATH,MAX_PATH/2);
m_FileNames.RemoveAll();
}
/************************************************************************
功能说明: CFileFindExt的析构函数
参数说明: 无
输出说明: 无
函数调用: Close()、类CStringArray的RemoveAll()
*************************************************************************/
CFileFindExt::~CFileFindExt()
{
Close();
m_FileNames.RemoveAll();
}
//以下三个函数是成员变量操作函数
/************************************************************************
功能说明: 设置文件名数组成员变量的大小和内存分配增量
参数说明: nNewSizen:当数组的大小;GrowBy:内存分配增量
输出说明: 无
函数调用: 类CStringArray的SetSize()
*************************************************************************/
void CFileFindExt::SetSize(int nNewSize, int nGrowBy)
{
m_FileNames.SetSize(nNewSize, nGrowBy);
}
/************************************************************************
功能说明: 获取文件名数组成员变量的大小
参数说明: 无
输出说明: 返回文件名数组成员变量的大小
函数调用: 类CStringArray的GetSize()
*************************************************************************/
int CFileFindExt::GetSize() const
{
return m_FileNames.GetSize();
}
/************************************************************************
功能说明: 获取数组成员变量中的文件名
参数说明: nFileIndex: 要获取的文件名在数组中的位置
输出说明: 返回文件名
函数调用: 类CStringArray的GetAt()
*************************************************************************/
CString CFileFindExt::GetAt(int nFileIndex) const
{
return m_FileNames.GetAt(nFileIndex);
}
//以下三个函数是对所有文件进行处理的成员函数
/************************************************************************
修改日期:2003-10-21
修改说明:为加快搜索速度,减少开销,用广度遍历实现非递归化
功能说明: 寻找指定目录下、指定扩展名的所有文件
调用格式: SearchFiles(DirName, FileExtName)
参数说明: DirName: 指定目录名
FileExtName:指定扩展名,缺省为所有类型文件
输出说明: 1、所有文件的相对路径文件名(相对于起始搜索路径)
保存在成员变量m_FileNames中;
2、成功返回true,分配内存不足时返回false
函数调用: FindFile(),FindNextFile(),GetFilePath()
*************************************************************************/
BOOL CFileFindExt::SearchFiles(CString DirName, CString FileExtName)
{
const int MAXQUEUELEN=MAX_PATH<<4; //同一层所有目录下的最大子目录数
char* Queue[MAXQUEUELEN];
CString root;
int rootlen=DirName.GetLength();
//统一根目录最末尾不含'\'
if(DirName.Right(1) != "\\")
root=DirName;
else
root=DirName.Left(--rootlen);
rootlen++;
int head=0;
int tail=0;
Queue[tail++]="";
char* str;
CString strPath;
do{
strPath=Queue[head];
if (strPath!="")
strPath=root+"\\"+strPath+_T("\\*.*");
else
strPath=root+strPath+_T("\\*.*");
BOOL NotEndofCurDir = FindFile(strPath);
while (NotEndofCurDir)
{
NotEndofCurDir = FindNextFile();
if (IsDots())
continue;
// 若是子目录
if (IsDirectory())
{
//保存相对路径于队列中
strPath = GetFilePath();
int len=strPath.GetLength();
strPath = strPath.Right(len-rootlen);
len-=rootlen;
if ((tail+1)%MAXQUEUELEN==head)
{
//队列已满
AfxMessageBox("同一层子目录太多!");
//关闭和释放队列空间
for (int i=head; head!=tail; )
{
str=Queue[head];
if (str!="")
delete [] str;
head=(head+1)%MAXQUEUELEN;
}
return false;
}
str=new char[len+1];
strcpy(str,(LPCTSTR)strPath);
Queue[tail]=str;
tail=(tail+1)%MAXQUEUELEN;
if (!NotEndofCurDir)
break;
}
else
{
//处理当前访问的文件
CString FileName=GetFilePath();
FileName = FileName.Right(FileName.GetLength()-rootlen);
if (FileExtName.Compare("*.*"))
{
CString ext=FileName.Right(3);
if (!ext.CompareNoCase(FileExtName.Right(3)))
m_FileNames.Add(FileName);
}
else
m_FileNames.Add(FileName);
}
} //End of while (NotEndofCurDir)
str=Queue[head];
if (str!="")
delete [] str;
head=(head+1)%MAXQUEUELEN;
} while (head!=tail);
Close();
//m_iFiles=m_FileNames.GetSize();
return true;
}
/************************************************************************
修改日期:2003-10-21
修改说明:为加快搜索速度,减少开销,用广度遍历实现非递归化
功能说明: 处理指定目录下、指定扩展名的所有文件
调用格式: DoProcess(DirName, process, FileExtName)
参数说明: DirName: 指定目录名
process: 一个参数型处理函数批针PROFUN1
FileExtName:指定扩展名,缺省为所有类型文件
输出说明: 1、对所有文件处理都成功,则返回true;
2、某一文件处理出错(函数process()返回false),或分配内存不足时,
则终止搜索,返回false
函数调用: process(),FindFile(),FindNextFile(),GetFilePath()
*************************************************************************/
BOOL CFileFindExt::DoProcess(CString DirName, PROFUN1 process, CString FileExtName)
{
const int MAXQUEUELEN=MAX_PATH<<4; //同一层所有目录下的最大子目录数
char* Queue[MAXQUEUELEN];
CString root;
int rootlen=DirName.GetLength();
//统一根目录最末尾不含'\'
if(DirName.Right(1) != "\\")
root=DirName;
else
root=DirName.Left(--rootlen);
rootlen++;
int head=0;
int tail=0;
Queue[tail++]="";
char* str;
CString strPath;
do{
strPath=Queue[head];
if (strPath!="")
strPath=root+"\\"+strPath+_T("\\*.*");
else
strPath=root+strPath+_T("\\*.*");
BOOL NotEndofCurDir = FindFile(strPath);
while (NotEndofCurDir)
{
NotEndofCurDir = FindNextFile();
if (IsDots())
continue;
// 若是子目录
if (IsDirectory())
{
//保存相对路径于队列中
strPath = GetFilePath();
int len=strPath.GetLength();
strPath = strPath.Right(len-rootlen);
len-=rootlen;
if ((tail+1)%MAXQUEUELEN==head)
{
//队列已满
AfxMessageBox("同一层子目录太多!");
//关闭和释放队列空间
for (int i=head; head!=tail; )
{
str=Queue[head];
if (str!="")
delete [] str;
head=(head+1)%MAXQUEUELEN;
}
return false;
}
str=new char[len+1];
strcpy(str,(LPCTSTR)strPath);
Queue[tail]=str;
tail=(tail+1)%MAXQUEUELEN;
if (!NotEndofCurDir)
break;
}
else
{
//处理当前访问的文件
CString FileName=GetFilePath();
if (FileExtName.Compare("*.*"))
{
CString ext=FileName.Right(3);
if (!ext.CompareNoCase(FileExtName.Right(3)))
{
if (!process(FileName))
return false;
}
}
else
{
if (!process(FileName))
return false;
}
}
} //End of while (NotEndofCurDir)
str=Queue[head];
if (str!="")
delete [] str;
head=(head+1)%MAXQUEUELEN;
} while (head!=tail);
Close();
return true;
}
/************************************************************************
修改日期:2003-10-21
修改说明:为加快搜索速度,减少开销,用广度遍历实现非递归化
功能说明: 处理指定目录下、指定扩展名的所有文件
调用格式: DoProcess(DirName, process, DstDir, SrcFileExt, DstFileExt)
参数说明: DirName: 指定目录名
process: 两个参数型处理函数批针PROFUN2
DstDir: 目标文件存放根目录名
SrcFileExt: 源文件扩展名,缺省为所有类型文件
DstFileExt: 目标文件扩展名,缺省为所有类型文件
输出说明: 1、对所有文件处理都成功,则返回true;
2、某一文件处理出错(函数process()返回false),或分配内存不足时,
则终止搜索,返回false
函数调用: process(),FindFile(),FindNextFile(),GetFilePath()
*************************************************************************/
BOOL CFileFindExt::DoProcess(CString DirName, PROFUN2 process, CString DstDir,
CString SrcFileExt, CString DstFileExt)
{
const int MAXQUEUELEN=MAX_PATH<<4; //同一层所有目录下的最大子目录数
char* Queue[MAXQUEUELEN];
CString root;
int rootlen=DirName.GetLength();
//统一根目录最末尾不含'\'
if(DirName.Right(1) != "\\")
root=DirName;
else
root=DirName.Left(--rootlen);
rootlen++;
//求目标目录的根目录
CString Dstroot;
int loc=DstDir.Find(':');
if (loc==1) //DstDir为绝对路径
Dstroot=DstDir;
else
{
//若DstDir为相对路径,
//则目标目录路径的根目录为DirName父目录+DstDir
loc=root.ReverseFind('\\');
Dstroot=root.Left(loc)+"\\"+DstDir;
if (Dstroot.Right(1)=="\\")
Dstroot=Dstroot.Left(Dstroot.GetLength()-1);//统一目录最末尾不含'\'
}
CreateDirectory(Dstroot,NULL);
Dstroot+="\\"; //统一目录最末尾加'\'
int head=0;
int tail=0;
Queue[tail++]="";
char* str;
CString strPath;
do{
strPath=Queue[head];
if (strPath!="")
strPath=root+"\\"+strPath+_T("\\*.*");
else
strPath=root+strPath+_T("\\*.*");
BOOL NotEndofCurDir = FindFile(strPath);
while (NotEndofCurDir)
{
NotEndofCurDir = FindNextFile();
if (IsDots())
continue;
// 若是子目录
if (IsDirectory())
{
//保存相对路径于队列中
strPath = GetFilePath();
int len=strPath.GetLength();
strPath = strPath.Right(len-rootlen);
len-=rootlen;
if ((tail+1)%MAXQUEUELEN==head)
{
//队列已满
AfxMessageBox("同一层子目录太多!");
//关闭和释放队列空间
for (int i=head; head!=tail; )
{
str=Queue[head];
if (str!="")
delete [] str;
head=(head+1)%MAXQUEUELEN;
}
return false;
}
str=new char[len+1];
strcpy(str,(LPCTSTR)strPath);
Queue[tail]=str;
tail=(tail+1)%MAXQUEUELEN;
if (!NotEndofCurDir)
break;
}
else
{
//处理当前访问的文件
CString FileName=GetFilePath();
CString DstFileDir=GetRoot();
//拼接目标目录
//也可定义别的目录拼接方式
int len=DstFileDir.GetLength();
DstFileDir = DstFileDir.Right(len-rootlen);
if (DstFileDir.Right(1)=="\\") //统一目录最末尾不含'\'
DstFileDir=DstFileDir.Left(DstFileDir.GetLength()-1);
if (DstFileDir!="")
DstFileDir=Dstroot+DstFileDir+"\\";
else
DstFileDir=Dstroot+DstFileDir;
CString FileTitle=GetFileTitle();
CString DstFile=DstFileDir+FileTitle+DstFileExt.Right(4);
if (SrcFileExt.Compare("*.*")) //指定扩展名
{
CString ext=FileName.Right(3);
if (!ext.CompareNoCase(SrcFileExt.Right(3)))
{
CreateDirectory(DstFileDir,NULL);
if (!process(FileName,DstFile))
return false;
}
}
else //是"*.*"
{
CreateDirectory(DstFileDir,NULL);
if (!process(FileName,DstFile))
return false;
}
}
} //End of while (NotEndofCurDir)
str=Queue[head];
if (str!="")
delete [] str;
head=(head+1)%MAXQUEUELEN;
} while (head!=tail);
Close();
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -