Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Recursive CFileFind problem [modified]

Recursive CFileFind problem [modified]

Scheduled Pinned Locked Moved C / C++ / MFC
csshelpquestion
10 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mr_Gbg
    wrote on last edited by
    #1

    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

    F D L 3 Replies Last reply
    0
    • M Mr_Gbg

      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

      F Offline
      F Offline
      Frank Seidler
      wrote on last edited by
      #2

      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

      D 1 Reply Last reply
      0
      • M Mr_Gbg

        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

        D Offline
        D Offline
        David Crow
        wrote on last edited by
        #3

        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 of CountFiles(), 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

        M 1 Reply Last reply
        0
        • F Frank Seidler

          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

          D Offline
          D Offline
          David Crow
          wrote on last edited by
          #4

          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

          L 1 Reply Last reply
          0
          • D David Crow

            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

            L Offline
            L Offline
            Luc Pattyn
            wrote on last edited by
            #5

            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.

            D 1 Reply Last reply
            0
            • L Luc Pattyn

              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.

              D Offline
              D Offline
              David Crow
              wrote on last edited by
              #6

              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

              L M 2 Replies Last reply
              0
              • D David Crow

                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

                L Offline
                L Offline
                Luc Pattyn
                wrote on last edited by
                #7

                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.

                1 Reply Last reply
                0
                • M Mr_Gbg

                  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

                  L Offline
                  L Offline
                  Luc Pattyn
                  wrote on last edited by
                  #8

                  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.

                  1 Reply Last reply
                  0
                  • D David Crow

                    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 of CountFiles(), 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

                    M Offline
                    M Offline
                    Mr_Gbg
                    wrote on last edited by
                    #9

                    Good Questions, both of them! Sloppy programming I guess is the answer. Fixed now, thanks! I've tried the whole global count variable thing as well, I still can't see a way around this... Grrr! X|

                    1 Reply Last reply
                    0
                    • D David Crow

                      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

                      M Offline
                      M Offline
                      Mr_Gbg
                      wrote on last edited by
                      #10

                      Thank you, David! :-D I tried your code, and it works like a charm!! I'm still not certain what was wrong with the original function, but that investigation has to wait for another day! ;P Anyhow, thank you all for your help, David in perticular!

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups