Recursive hard disk search with FindFirstFile & FindNextFile C++

后端 未结 2 832
-上瘾入骨i
-上瘾入骨i 2020-12-04 02:11

I am failing to see where i am going wrong. This current code skips straight to closefile. NOt processing any files, i may just be missing something obvious and it has been

相关标签:
2条回答
  • 2020-12-04 02:43

    You have quite a few logic bugs in your code. Try this instead (you did not indicate which compiler you are using, so I am assuming C++Builder, which has an uppercase-S String class. Adjust the code as needed if you are using a different compiler):

    String Copy::SearchDrive(const String& strFile, const String& strFilePath, const bool& bRecursive, const bool& bStopWhenFound) const
    {
        String strFoundFilePath;
        WIN32_FIND_DATA file;
    
        String strPathToSearch = strFilePath;
        if (!strPathToSearch.IsEmpty())
            strPathToSearch = IncludeTrailingPathDelimiter(strPathToSearch);
    
        HANDLE hFile = FindFirstFile((strPathToSearch + "*").c_str(), &file);
        if (hFile != INVALID_HANDLE_VALUE)
        {
            do
            {
                String strTheNameOfTheFile = file.cFileName;
    
                // It could be a directory we are looking at
                // if so look into that dir
                if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    if ((strTheNameOfTheFile != ".") && (strTheNameOfTheFile != "..") && (bRecursive))
                    {
                        strFoundFilePath = SearchDrive(strFile, strPathToSearch + strTheNameOfTheFile, bRecursive, bStopWhenFound);
    
                        if (!strFoundFilePath.IsEmpty() && bStopWhenFound)
                            break;
                    }
                }
                else
                {
                    if (strTheNameOfTheFile == strFile)
                    {
                        strFoundFilePath = strPathToSearch + strFile;
    
                        /// TODO
                        // ADD TO COLLECTION TYPE
    
                        if (bStopWhenFound)
                            break;
                    }
                }
            }
            while (FindNextFile(hFile, &file));
    
            FindClose(hFile);
        }
    
        return strFoundFilePath;
    }
    

    String strFoundFilePath = SearchDrive("file.ext", "C:\\", ...);
    

    UPDATE: An alternative implementation of SearchDrive() that does not keep multiple search handles open while recursing through sub-directories:

    #include <memory>
    
    String Copy::SearchDrive(const String& strFile, const String& strFilePath, const bool& bRecursive, const bool& bStopWhenFound) const
    {
        String strFoundFilePath;
        WIN32_FIND_DATA file;
    
        String strPathToSearch = strFilePath;
        if (!strPathToSearch.IsEmpty())
            strPathToSearch = IncludeTrailingPathDelimiter(strPathToSearch);
    
        HANDLE hFile = FindFirstFile((strPathToSearch + "*").c_str(), &file);
        if (hFile != INVALID_HANDLE_VALUE)
        {
            std::auto_ptr<TStringList> subDirs;
    
            do
            {
                String strTheNameOfTheFile = file.cFileName;
    
                // It could be a directory we are looking at
                // if so look into that dir
                if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    if ((strTheNameOfTheFile != ".") && (strTheNameOfTheFile != "..") && (bRecursive))
                    {
                        if (subDirs.get() == NULL)
                            subDirs.reset(new TStringList);
    
                        subDirs->Add(strPathToSearch + strTheNameOfTheFile);
                    }
                }
                else
                {
                    if (strTheNameOfTheFile == strFile)
                    {
                        strFoundFilePath = strPathToSearch + strFile;
    
                        /// TODO
                        // ADD TO COLLECTION TYPE
    
                        if (bStopWhenFound)
                            break;
                    }
                }
            }
            while (FindNextFile(hFile, &file));
    
            FindClose(hFile);
    
            if (!strFoundFilePath.IsEmpty() && bStopWhenFound)
                return strFoundFilePath;
    
            if (subDirs.get() != NULL)
            {
                for (int i = 0; i < subDirs->Count; ++i)
                {
                    strFoundFilePath = SearchDrive(strFile, subDirs->Strings[i], bRecursive, bStopWhenFound);
    
                    if (!strFoundFilePath.IsEmpty() && bStopWhenFound)
                        break;
                }
            }
        }
    
        return strFoundFilePath;
    }
    
    0 讨论(0)
  • 2020-12-04 02:56

    Your condition is incorrect, you should compare to to INVALID_HANDLE_VALUE

     if ( hFile != INVALID_HANDLE_VALUE)
    

    Besides you skip the first matching file returned by FindFirstFile, is that what you want?

    Also I believe you need a wildcard c:\\* otherwise it will only match c:\\ itself

    hFile = FindFirstFile("C:\\*", &file);
    
    0 讨论(0)
提交回复
热议问题