Recursive CFileFind problem [modified]
-
I have a recursive CountFiles function that I just can't get to work properly. It counts all files in all directories under a given root. But when I run it it allways returns somewhat less nr of files than expected. I suspect I've made a logical dive somewhere, but I just can't see it! :(( The code below is supposed to return 13.301 files for my image library, but comes with 12.110... Can anybody see what my mistake is??:rose:
int CBackupImagesDlg::CountFiles(const CString strRoot)
{
int count=0;
CFileFind f;
CString strDir = strRoot;
strDir +=+ _T("\\*");
CString csNewPath(_T(""));if(f.FindFile(LPCTSTR(strDir))) { while(f.FindNextFile() ) { BOOL bDir=f.IsDirectory(); BOOL bDot=f.IsDots(); csNewPath = f.GetFilePath(); if (bDot) continue; if(bDir) { count=count + CountFiles(csNewPath); } else // not dot, not dir = count as file { count++; } }//while... } f.Close(); return count;
}
modified on Thursday, March 3, 2011 12:56 PM
-
I have a recursive CountFiles function that I just can't get to work properly. It counts all files in all directories under a given root. But when I run it it allways returns somewhat less nr of files than expected. I suspect I've made a logical dive somewhere, but I just can't see it! :(( The code below is supposed to return 13.301 files for my image library, but comes with 12.110... Can anybody see what my mistake is??:rose:
int CBackupImagesDlg::CountFiles(const CString strRoot)
{
int count=0;
CFileFind f;
CString strDir = strRoot;
strDir +=+ _T("\\*");
CString csNewPath(_T(""));if(f.FindFile(LPCTSTR(strDir))) { while(f.FindNextFile() ) { BOOL bDir=f.IsDirectory(); BOOL bDot=f.IsDots(); csNewPath = f.GetFilePath(); if (bDot) continue; if(bDir) { count=count + CountFiles(csNewPath); } else // not dot, not dir = count as file { count++; } }//while... } f.Close(); return count;
}
modified on Thursday, March 3, 2011 12:56 PM
Hi! You are missing 1 file per call to countfiles(). Simply move the while to the bottom of the loop to solve this.
if ( f.FindFile(LPCTSTR(strDir)))
{
do
{
...
}
while ( f.FindNextFile() );
}Regards Frank
-
I have a recursive CountFiles function that I just can't get to work properly. It counts all files in all directories under a given root. But when I run it it allways returns somewhat less nr of files than expected. I suspect I've made a logical dive somewhere, but I just can't see it! :(( The code below is supposed to return 13.301 files for my image library, but comes with 12.110... Can anybody see what my mistake is??:rose:
int CBackupImagesDlg::CountFiles(const CString strRoot)
{
int count=0;
CFileFind f;
CString strDir = strRoot;
strDir +=+ _T("\\*");
CString csNewPath(_T(""));if(f.FindFile(LPCTSTR(strDir))) { while(f.FindNextFile() ) { BOOL bDir=f.IsDirectory(); BOOL bDot=f.IsDots(); csNewPath = f.GetFilePath(); if (bDot) continue; if(bDir) { count=count + CountFiles(csNewPath); } else // not dot, not dir = count as file { count++; } }//while... } f.Close(); return count;
}
modified on Thursday, March 3, 2011 12:56 PM
Mr_Gbg wrote:
The code below is supposed to return 13.301 files for my image library...
According to what?
Mr_Gbg wrote:
strDir +=+ _T("\\*");
What is
+=+
?Mr_Gbg wrote:
if(f.FindFile(LPCTSTR(strDir)))
Why the superfluous cast?
Mr_Gbg wrote:
The code below is supposed to return 13.301 files for my image library, but comes with 12.110... Can anybody see what my mistake is??[Rose]
To make sure your recursion logic is sound, you might try moving
count
outside ofCountFiles()
, either by making it global or a member variable."One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
-
Hi! You are missing 1 file per call to countfiles(). Simply move the while to the bottom of the loop to solve this.
if ( f.FindFile(LPCTSTR(strDir)))
{
do
{
...
}
while ( f.FindNextFile() );
}Regards Frank
MSDN states that you must call
FindNextFile()
at least once before calling any other member function. Are you saying that's no longer required?"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
-
MSDN states that you must call
FindNextFile()
at least once before calling any other member function. Are you saying that's no longer required?"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
Very strange indeed, MSDN[^] says certain functions require a FindNextFile being executed first, however as FindFile returns the first file, and FindNextFile finds the next ones, how could one execute those functions on the first file at all? Anyway, the Win32 functions FindFirstFile, FindNextFile don't show such a remark, although here[^] is a note suggesting to call
GetFileInformationByHandle()
. So did the MFC guys ignore the note? or is it no longer relevant? :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
Very strange indeed, MSDN[^] says certain functions require a FindNextFile being executed first, however as FindFile returns the first file, and FindNextFile finds the next ones, how could one execute those functions on the first file at all? Anyway, the Win32 functions FindFirstFile, FindNextFile don't show such a remark, although here[^] is a note suggesting to call
GetFileInformationByHandle()
. So did the MFC guys ignore the note? or is it no longer relevant? :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
I've always coded my recursive
CFileFind
code as follows:void ProcessFolder( LPCTSTR lpszPath )
{
CString strPath(lpszPath);
CFileFind fileFind;if (strPath.Right(1) != \_T('\\\\')) strPath += \_T('\\\\'); BOOL bFound = fileFind.FindFile(strPath + \_T("\*.\*")); while (bFound) { bFound = fileFind.FindNextFile(); if (fileFind.IsDirectory()) { if (! fileFind.IsDots()) ProcessFolder(fileFind.GetFilePath()); } else { // file } }
}
It's worked for years like that.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
-
I've always coded my recursive
CFileFind
code as follows:void ProcessFolder( LPCTSTR lpszPath )
{
CString strPath(lpszPath);
CFileFind fileFind;if (strPath.Right(1) != \_T('\\\\')) strPath += \_T('\\\\'); BOOL bFound = fileFind.FindFile(strPath + \_T("\*.\*")); while (bFound) { bFound = fileFind.FindNextFile(); if (fileFind.IsDirectory()) { if (! fileFind.IsDots()) ProcessFolder(fileFind.GetFilePath()); } else { // file } }
}
It's worked for years like that.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
you're right, I had to read once more to discover in MFC FindFile opens the search but does not return the first file, so FindNextFile is needed to find even the first file; this is different from how Win32 works, and IMO quite confusing (FindFile should have been named PrepareFileSearch or something similar). This also means the first reply (by Frank) is wrong, and the wrong count hasn't been explained yet. :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
I have a recursive CountFiles function that I just can't get to work properly. It counts all files in all directories under a given root. But when I run it it allways returns somewhat less nr of files than expected. I suspect I've made a logical dive somewhere, but I just can't see it! :(( The code below is supposed to return 13.301 files for my image library, but comes with 12.110... Can anybody see what my mistake is??:rose:
int CBackupImagesDlg::CountFiles(const CString strRoot)
{
int count=0;
CFileFind f;
CString strDir = strRoot;
strDir +=+ _T("\\*");
CString csNewPath(_T(""));if(f.FindFile(LPCTSTR(strDir))) { while(f.FindNextFile() ) { BOOL bDir=f.IsDirectory(); BOOL bDot=f.IsDots(); csNewPath = f.GetFilePath(); if (bDot) continue; if(bDir) { count=count + CountFiles(csNewPath); } else // not dot, not dir = count as file { count++; } }//while... } f.Close(); return count;
}
modified on Thursday, March 3, 2011 12:56 PM
what is telling you there would be 13.301 files? and how many folders are there? some ideas: - hidden files (your code would see them all, or throw an exception, so can't really be that); - maybe folders also count as files in the tool that said 13301; - there may be something fishy with empty extensions; - there might be a difference between * and *.*; - there is something peculiar (and silly) in the way Windows treats wildcards in extensions; I don't recall the details. - I wouldn't be surprised if some of the above would depend on the actual file system (FAT, NTFS, ...). I suggest you try your tool and your code on a pretty small set of files and folders, and experiment a bit. :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
Mr_Gbg wrote:
The code below is supposed to return 13.301 files for my image library...
According to what?
Mr_Gbg wrote:
strDir +=+ _T("\\*");
What is
+=+
?Mr_Gbg wrote:
if(f.FindFile(LPCTSTR(strDir)))
Why the superfluous cast?
Mr_Gbg wrote:
The code below is supposed to return 13.301 files for my image library, but comes with 12.110... Can anybody see what my mistake is??[Rose]
To make sure your recursion logic is sound, you might try moving
count
outside ofCountFiles()
, either by making it global or a member variable."One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
-
I've always coded my recursive
CFileFind
code as follows:void ProcessFolder( LPCTSTR lpszPath )
{
CString strPath(lpszPath);
CFileFind fileFind;if (strPath.Right(1) != \_T('\\\\')) strPath += \_T('\\\\'); BOOL bFound = fileFind.FindFile(strPath + \_T("\*.\*")); while (bFound) { bFound = fileFind.FindNextFile(); if (fileFind.IsDirectory()) { if (! fileFind.IsDots()) ProcessFolder(fileFind.GetFilePath()); } else { // file } }
}
It's worked for years like that.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather