mercredi 23 décembre 2015

Trouble with recursive file search

I am trying to write a script to recursivly scan a disk and return the total numbers of directories, files and also display the largest file found. I know that there is much information to find on StackOverflow or on the web, but all the examples I found so far seem to have issues with really scan a disk recursivly. Below script uses the FindFile and FindNextFile functions to scan for files. If the file atribute returns that the the function found a directory it writes the name into a list to be searched later. After the current directory has been searched the script takes the first item (being a directory to be scanned) of the list, removes that item from the list and scans this directory.

My problem is that after scanning a few hundred directories and subdirectories the program end with an error

Unhandled exception at ..... (ntdll.dll) in File Lister 6.0.exe: .....: Stack overflow

or

Unhandled exception at ..... (ntdll.dll) in File Lister 6.0.exe: ......: Access violation writing location 0x00f30fe8.

But the then scanned directory is never the same.

I have been trying to solves this issue but can not find a clear reason for it. Therefore I would much appreciate if someone could help

Below is my code. I know it's looking very novice, my apologises for that

    #include <windows.h>
    #include <iostream>
    #include <fstream>
    #include <conio.h>
    #include <ctype.h>
    #include <string>
    #include <string.h>
    #include <stdio.h>
    #include <direct.h>
    #include <list>

    using namespace std;


    list <string> myList;
    std::list<string>::iterator it;

       int siZe;
       int siZekB;
       bool  bSearchSubdirectories=true;
       HANDLE handle;
       LPCTSTR strPattern;
       std::string temp;
       std::string temp1;
       std::string temp2;
       std::string temp3;
       WIN32_FIND_DATA search_data;
       int DIRPlace;
       int MaxDir=400000000;

       int telDIR=1;
       int telFILES=1;
       double LargestFile=0;
       string LargestFileName;
       string SDir;


    std::string string_to_hex(const std::string& input)
    {
        static const char* const lut = "0123456789ABCDEF";
        size_t len = input.length();

        std::string output;
        output.reserve(2 * len);
        for (size_t i = 0; i < len; ++i)
        {
            const unsigned char c = input[i];
            output.push_back(lut[c >> 4]);
            output.push_back(lut[c & 15]);
        }
        return output;
    }



    int SearchDirectory(string FileSearch ,string refvecFiles,
                        bool bSearchSubdirectories)
    {  

       WIN32_FIND_DATA search_data;
       memset(&search_data, 0, sizeof(WIN32_FIND_DATA));
       HANDLE handle = FindFirstFile((refvecFiles+FileSearch).c_str(), &search_data);  
       temp = refvecFiles;
       while(handle != INVALID_HANDLE_VALUE)   {

               do{
                   if (search_data.cFileName[0]!='.'){  
                           temp2=search_data.dwFileAttributes;
                           temp3=string_to_hex(temp2);
                           DIRPlace=strlen(temp3.c_str())-1;
                       switch (temp3[DIRPlace-1])
                       {
                          case '1':    //Directory
                               temp = refvecFiles;
                               temp1=search_data.cFileName;
                               temp2=search_data.dwFileAttributes;
                               myList.push_back(temp+temp1);
                               telDIR++;
                               break; 
                         default:   //Other types (Files etc)
                               siZe=(search_data.nFileSizeHigh * (MAXDWORD+1)) + search_data.nFileSizeLow;
                               siZekB=((search_data.nFileSizeHigh * (MAXDWORD+1)) + search_data.nFileSizeLow)/1024;
                               temp = refvecFiles;
                               temp1=search_data.cFileName;
                               temp2=search_data.dwFileAttributes;
                               if (siZekB>LargestFile){
                                  LargestFile=siZekB;
                                  LargestFileName=temp.substr(0, temp.size()) + "\\" + temp1;
                               }
                               telFILES++;
                               break;
                       }
                   }  
                }while      (FindNextFile(handle, &search_data) != FALSE && telDIR<MaxDir);
                                  string line,SearD, LineFiller,FrontString, BackString;


                      it=myList.begin();
                        SearD=*it+"\\\\";
                        myList.remove(*it);
                      if (SearD.length()>60)
                      {
                          FrontString=SearD.substr(0,10);
                          BackString=SearD.substr(SearD.length()-44);
                          LineFiller="......";
                          FrontString=FrontString+LineFiller+BackString;
                      }else{
                        FrontString=SearD;
                      }
                      cout<<"Exploring:                                                              "<<"\r";
                      cout<<"Exploring: "<<FrontString<<"\r\r";
                      SearchDirectory("\\*",SearD, false);     
       }
       FindClose(handle);
       return 0;

    }





    int main(int argc, char* argv[])
    {   
        std::cout<< "Enter directory to be searched: ";
        getline(cin,SDir);
        std::cout<< "\n";
        try{
        SearchDirectory("\\*",SDir, false);
        }catch (int e)
  {
    cout << "An exception occurred. Exception Nr. " << e << '\n';
  }
                std::cout<< "\n"<<"\n";
        std::cout<<"Directories found: "<< telDIR<< "\n";
        std::cout<<"Files found: "<< telFILES<< "\n"; 
        std::cout<<"Largest File: "<<LargestFileName << " ("<< LargestFile << " kB)"<<"\n";     
        std::cout<<"press any key";
        getch();       
    }

Aucun commentaire:

Enregistrer un commentaire