recursive file search

前端 未结 6 902
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-06 13:49

I\'m trying to figure out how to work this thing out .. For some reason, it ends at a certain point.. I\'m not very good at recursion and I\'m sure the problem lies somewher

相关标签:
6条回答
  • 2021-01-06 14:24

    You are changing the value of your local wrkdir variable:

    wrkdir = wrkdir + L"\\" + file_data.cFileName;
    find_files( wrkdir );
    

    I think you have to call find_files there like this:

    find_files( wrkdir + L"\\" + file_data.cFileName );
    

    and not change the value of wrkdir.

    0 讨论(0)
  • 2021-01-06 14:26

    Recursive file search with dirent.h

    #include <iostream>
    #include <dirent.h>
    #include <string.h>    
    
    bool isUpDirecory(const char* directory) {
            if (strcmp(directory, "..") == 0 || strcmp(directory, ".") == 0)
                return true;
            else
                return false;
        }
    
        bool findFile(const std::string& fileName, const std::string& path,
                std::string& resultPath) {
            dirent* entry;
            DIR* dir = opendir(path.c_str());
    
            if (dir == NULL)
                return false;
    
            while ((entry = readdir(dir)) != NULL) {
                if (entry->d_type == DT_REG) {
                    if (fileName.compare(entry->d_name) == 0) {
                        resultPath = path + "/" + entry->d_name;
                        closedir(dir);
                        return true;
                    }
                }
            }
    
            rewinddir(dir);
    
            while ((entry = readdir(dir)) != NULL) {
                if (entry->d_type == DT_DIR) {
                    if (!isUpDirecory(entry->d_name)) {
                        std::string nextDirectoryPath = path + "/" + entry->d_name;
                        bool result = findFile(fileName, nextDirectoryPath, resultPath);
                        if (result == true) {
                            closedir(dir);
                            return true;
                        }
                    }
                }
            }
    
            closedir(dir);
            return false;
        }
    
        int main() {
            std::string path;
            bool result = findFile("text.txt", "/home/lamerman/", path);
            std::cout << path << std::endl;
            return 0;
        }
    
    0 讨论(0)
  • 2021-01-06 14:32

    Also, check out the implementation of the CFileFind MFC class.

    0 讨论(0)
  • 2021-01-06 14:34

    There are still several bugs in your code. Try this instead:

    void find_files( wstring wrkdir )
    {
        wstring wrkdirtemp = wrkdir;
        if( !wrkdirtemp.empty() && (wrkdirtemp[wrkdirtemp.length()-1] != L'\\')  )
        {
          wrkdirtemp += L"\\";
        }
    
        WIN32_FIND_DATA file_data = {0};
        HANDLE hFile = FindFirstFile( (wrkdirtemp + L"*").c_str(), &file_data );
    
        if( hFile == INVALID_HANDLE_VALUE )
        {
             return;
        }
    
        do
        {
            if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            {
                if( (wcscmp(file_data.cFileName, L".") != 0) && 
                    (wcscmp(file_data.cFileName, L"..") != 0) )
                {
                    find_files( wrkdirtemp + file_data.cFileName );
                }
            }
            else
            {
                if( (file_data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == 0 )
                {
                    results << wrkdirtemp << file_data.cFileName << endl;
                }
            }
        }
        while( FindNextFile( hFile, &file_data );
    
        FindClose( hFile );
    }
    
    0 讨论(0)
  • 2021-01-06 14:34

    You still have errors in your code:

    1. you ignore the results of the first search. you call FindFirstFile and handle if it fails. But if it succeeds you do not process already fetched file_data and overwrite it with FindNextFile.
    2. You don't close the search handle. Use FindClose for that.
    3. From your existing code it seems that fHandle is global - it shouldn't. It would break your recursion.

    Also I think that you can resolve all the issues in your code by paying more attention to MSDN sample provided in FindFirstFile documentation.

    0 讨论(0)
  • 2021-01-06 14:44

    From the FindFirstFile documentation:

    If the function fails or fails to locate files from the search string in the lpFileName parameter, the return value is INVALID_HANDLE_VALUE and the contents of lpFindFileData are indeterminate.

    You should only exit from the one iteration not the whole program:

       if( fHandle == INVALID_HANDLE_VALUE )
       {
         return;
       }
    

    And this may solve your other problem:

    else if( file_data.dwFileAttributes != FILE_ATTRIBUTE_HIDDEN && 
       file_data.dwFileAttributes != FILE_ATTRIBUTE_SYSTEM  &&
       wcscmp(file_data.cFileName, L".") != 0 && 
       wcscmp(file_data.cFileName, L"..") != 0
     )
    {
        results << wrkdir << "\\" << file_data.cFileName << endl;
    }
    

    Also see @fretje's answer as well. It gives another problem that your code has.

    Updated new: You need to use fHandle as a local variable as well, not global variable.

    Change to:

     HANDLE fHandle = FindFirstFile( temp.c_str(), &file_data );
    
    0 讨论(0)
提交回复
热议问题