void CFindFilesDlg::On
{
// TODO: 在此添加控件通知处理程序代码
CString c1;
CString stredit;
CString strtemp;
HANDLE hFile;
WIN32_FIND_DA
DWORD errorcode = 0;
m_Edit1.GetWindowText(c1); //要熟悉控件的基本使用
if(!c1.IsEmpty())
{
hFile=FindFirstFile("f:\\*.*",&fileinfo);
while(hFile!=INVALID_HANDLE_VALUE&&errorcode!=ERROR_NO_MORE_FILES)
{
//
strtemp=fileinfo.cFileName;
stredit=stredit+"\r\n";
stredit=stredit+strtemp;
FindNextFile(hFile,&fileinfo);
errorcode=GetLastError();
}
if(errorcode==ERROR_NO_MORE_FILES)
{
m_cedit1.SetWindowText(stredit);
MessageBox("检索结束");
}
CloseHandle(hFile);
}
}
在上述代码中FindFirstFile第一个个参数需要一个路径,但要写*.*,表示从所有文件中找到的第一个.但写f:或者f:双斜杠都返回无效句柄.
如果f:\\1.txt 则对特定文件进行搜索,返回找到的第一个
找到的文件的文件结构被记录在WIN32_FIND_DA
TA结构体里 FindNextFile第一个参数是FindFirstFile的返回值,可以接着上次结果继续寻找
但注意!!!!
但一个目录的文件被搜索一遍后,FindNextFile返回的WIN32_FIND_DA
TA结构体将重复找到最后一个找到的文件,而不会终止. 让循环结束的方法就是找上一次的报错码,然后看有没有ERROR_NO_MORE_FILES信息发生.
hFile的有效与否个人觉得还是取决于第一次的FindFirstFile结果,本程序后半段的运行主要还是errorcode!=ERROR_NO_MORE_FILES在控制.
使用FindFirstFile和FindNextFile查找某个目录下的所有文件(包括子目录)
一、在不使用mfc的程序中获得某个目录下的所有文件名称,包括子目录。把文件名称以一个固定的程度放入一个缓冲中,这个缓冲要足够的大,能容下所有的文件名称。
函数的输入为要查找的根目录,输出为存放所有文件名称的缓冲
算法:使用递归
二、代码:
void FindFileInDir(char* rootDir, char* strRet)
{
char fname[MAC_FILENAMELENOPATH];
ZeroMemory(fname, MAC_FILENAMELENOPATH);
WIN32_FIND_DA
TA fd; ZeroMemory(&fd, sizeof(WIN32_FIND_DA
TA));
HANDLE hSearch;
char filePathName[256];
char tmpPath[256];
ZeroMemory(filePathName, 256);
ZeroMemory(tmpPath, 256);
strcpy(filePathName, rootDir);
BOOL bSearchFinished = FALSE;
if( filePathName[strlen(filePathName) -1] != '\\' )
{strcat(filePathName, "\\");}
strcat(filePathName, "*");
hSearch = FindFirstFile(filePathName, &fd);
//Is directory
if( (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
{
strcpy(tmpPath, rootDir);
strcat(tmpPath, fd.cFileName);
FindFileInDir(tmpPath, strRet);
}
else if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
{
sprintf(fname, "%-50.50s", fd.cFileName);
strcat(strRet + strRet[strlen(strRet)] , fname);
}
while( !bSearchFinished )
{
if( FindNextFile(hSearch, &fd) )
{
if( (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
{
strcpy(tmpPath, rootDir);
strcat(tmpPath, fd.cFileName);
FindFileInDir(tmpPath, strRet);
}
else if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )//特别注意:当字符串相等时时,返回值=0
{
sprintf(fname, "%-50.50s", fd.cFileName);
strcat(strRet + strRet[strlen(strRet)] , fname);
}
}
else
{
if( GetLastError() == ERROR_NO_MORE_FILES ) //Normal Finished
{
bSearchFinished = TRUE;
}
else
bSearchFinished = TRUE; //Terminate Search
}
}
FindClose(hSearch);
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/caimouse/archive/2007/10/25/1844006.aspx
Windows API一日一练(58)FindFirstFile和FindNextFile函数 收藏
在开发软件的过程里,经常需要维护目录里的数据。比如在开发银行的信用卡系统里,由于每天创建的LOG非常多,那么一个很大的硬盘,在6个月后,就占用了很多空间。这时就有这样的一个需求,把所有超过6个月的LOG数据定期删除掉。要实现这个功能就得遍历整个目录,把文件名称和文件创建的时间都超过6个月时间的文件删除掉。因此,就需使用到下面的API函数FindFirstFile和FindNextFile来实现这样的功能,FindFirstFile函数是查找到目录下的第一个文件或目录,FindNextFile函数是查找下一文件或目录。
函数FindFirstFile、FindNextFile和FindClose声明如下:
WINBASEAPI
__out
HANDLE
WINAPI
FindFirstFileA(
__in LPCSTR lpFileName,
__out LPWIN32_FIND_DATAA lpFindFileData
);
WINBASEAPI
__out
HANDLE
WINAPI
FindFirstFileW(
__in LPCWSTR lpFileName,
__out LPWIN32_FIND_DATAW lpFindFileData
);
#ifdef UNICODE
#define FindFirstFile FindFirstFileW
#else
#define FindFirstFile FindFirstFileA
#endif // !UNICODE
WINBASEAPI
BOOL
WINAPI
FindNextFileA(
__in HANDLE hFindFile,
__out LPWIN32_FIND_DATAA lpFindFileData
);
WINBASEAPI
BOOL
WINAPI
FindNextFileW(
__in HANDLE hFindFile,
__out LPWIN32_FIND_DATAW lpFindFileData
);
#ifdef UNICODE
#define FindNextFile FindNextFileW
#else
#define FindNextFile FindNextFileA
#endif // !UNICODE
WINBASEAPI
BOOL
WINAPI
FindClose(
__inout HANDLE hFindFile
);
lpFileName是目录名称。一般使用通配符。
lpFindFileData是找到的文件或目录属性。
hFindFile是下一个文件或目录的句柄。
调用函数的例子如下:
#001 #pragma once
#002
#003 //
#004 //遍历一个目录的文件。
#005 //蔡军生 2007/10/25 QQ:9073204 深圳
#006 //
#007 class CFindFile
#008 {
#009 public:
#010
#011 CFindFile(void)
#012 {
#013 m_hFind = INVALID_HANDLE_VALUE;
#014 m_bFound = false;
#015 memset(&m_FindFileData,0,sizeof(m_FindFileData));
#016 }
#017
#018 ~CFindFile(void)
#019 {
#020 if (m_hFind != INVALID_HANDLE_VALUE)
#021 {
#022 ::FindClose(m_hFind);
#023 }
#024 }
#025
#026 //找到第一个文件。
#027 void First(LPCTSTR lpFileName)
#028 {
#029 m_hFind = ::FindFirstFile(lpFileName,&m_FindFileData);
#030 if (m_hFind != INVALID_HANDLE_VALUE)
#031 {
#032 m_bFound = true;
#033 }
#034 else
#035 {
#036 m_bFound = false;
#037 }
#038 }
#039
#040 //查找一下文件。
#041 void Next(void)
#042 {
#043 m_bFound = FindNextFile(m_hFind, &m_FindFileData) ? true:false;
#044 }
#045
#046 //是否可以查找一下文件。
#047 bool IsOK(void) const
#048 {
#049 return m_bFound;
#050 }
#051
#052 //返回当前文件的属性。
#053 const WIN32_FIND_DATA& GetCurFile(void)
#054 {
#055 return m_FindFileData;
#056 }
#057
#058 protected:
#059 HANDLE m_hFind; //保存当查找的位置句柄。
#060 bool m_bFound; //当前查找是否成功。
#061 WIN32_FIND_DATA m_FindFileData;//保存当前文件的属性。
#062
#063 };
#064
使用如下:
#001 //查找文件。
#002 CFindFile findDemo;
#003 for (findDemo.First(_T(".\\*"));
#004 findDemo.IsOK();
#005 findDemo.Next())
#006 {
#007 //
#008 OutputDebugString(findDemo.GetCurFile().cFileName);
#009 OutputDebugString(_T("\r\n"));
#010 }
#011__________________________________________________________________________________________
问题一:
三个文件:readbook.exe, readbook1.exe,readbook2.exe;查找首字母是r,结尾是".exe"的文件名插入list box,结果只找到了两个readbook.exe,readbook1.exe; 用的是CFile类;
问题二:
将本机目录建成一棵树,结果在d:盘下找到两个名为vc的目录,别的目录有时也会有类似情况;我用的是FILE类,API:FindFile,FindNextFile,FindClose
FindNextFile会漏掉文件吗?相关解决方法:1、
FindNextFile会漏掉文件吗?推荐解答:
1.不可能吧,大概你的循环程序没处理对.可以贴出来看看.
2.还是你程序的问题,将代码贴出来吧.
要不将源文件发给我也行.
2、
问题一的源程序段
CFileFind fFind;
fFind.FindFile(m_strListFind,0); //m_strListFind即为路径,如d:\ok\R* ,以R开头
int i=0;
do
{
if (fFind.IsDirectory() || fFind.IsDots()) continue;
if(fFind.GetFileName().Right(m_App.GetLength())!=m_App) continue;//m_App即为".exe"
m_List.AddString(fFind.GetFileName());
i++;
}
while(fFind.FindNextFile());
3、
FindNextFile会漏掉文件吗?推荐解答:
程序中有错误, CFileFind::FindNextFile()方法找到最后一个文件后会返回0,此时退出循环,所以你找不到文件了. 因该把FindNextFile放在前面调用,参考以下例子就很清楚了
CFileFind finder;
BOOL bWorking = finder.FindFile("*.*");
while (bWorking)
{
bWorking = finder.FindNextFile();
cout << (LPCTSTR) finder.GetFileName() << endl;
}
4、
FindNextFile会漏掉文件吗?推荐解答:
1.msdn上提到,在调用GetFileName等前起码的调用一次FindNextFile
2.在FindFile返回为true的时候,至少有一项符合搜索结果,此时调用FindNextFile,宜可能返回false;
解决办法
if (fFind.FindFile(path))
{
while(cfind.FindNextfile())
{
the operation code;
}
the operation code;//这里再调用一边
}
5、
多谢!
评论