Я пытаюсь написать сценарий для рекурсивного сканирования диска и возврата общего количества каталогов, файлов, а также отображения самого большого найденного файла. Я знаю, что есть много информации, которую можно найти в StackOverflow или в Интернете, но все примеры, которые я нашел до сих пор, по-видимому, имеют проблемы с реальной рекурсией сканирования диска. Ниже сценарий использует функции FindFile и FindNextFile для сканирования файлов. Если атрибут файла возвращает, что функция обнаружила каталог, она записывает имя в список, который будет искать позже. После поиска текущего каталога сценарий берет первый элемент (являющийся сканируемым каталогом) списка, удаляет этот элемент из списка и сканирует этот каталог.Проблема с рекурсивным поиском файлов
Моя проблема заключается в том, что после сканирования несколько сотен каталогов и подкаталогов в конце программы с ошибкой
Unhandled exception at ..... (ntdll.dll) in File Lister 6.0.exe: .....: Stack overflow
или
Unhandled exception at ..... (ntdll.dll) in File Lister 6.0.exe: ......: Access violation writing location 0x00f30fe8.
Но тогда проверяемой директории никогда не то же самое.
Я пытался решить эту проблему, но не могу найти ясную причину этого. Поэтому я был бы очень признателен, если бы кто-то мог помочь
Ниже мой код. Я знаю, что очень новичок смотрит, мои извинения за это
#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 = "ABCDEF";
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();
}
EDIT: Ниже приведен снимок из отладчика Call Stack
> File Lister 6.0.exe!std::operator<<<std::char_traits<char> >(std::basic_ostream<char,std::char_traits<char> > & _Ostr={...}, const char * _Val=0x000d51c8) Line 791 + 0x20 bytes C++
File Lister 6.0.exe!SearchDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > FileSearch="\*", std::basic_string<char,std::char_traits<char>,std::allocator<char> > refvecFiles="c:\\boost\\numeric\\interval\\", bool bSearchSubdirectories=false) Line 110 + 0x16 bytes C++
File Lister 6.0.exe!SearchDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > FileSearch="\*", std::basic_string<char,std::char_traits<char>,std::allocator<char> > refvecFiles="c:\\boost\\numeric\\conversion\\", bool bSearchSubdirectories=false) Line 113 C++
File Lister 6.0.exe!SearchDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > FileSearch="\*", std::basic_string<char,std::char_traits<char>,std::allocator<char> > refvecFiles="c:\\boost\\multi_index\\detail\\", bool bSearchSubdirectories=false) Line 113 C++
File Lister 6.0.exe!SearchDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > FileSearch="\*", std::basic_string<char,std::char_traits<char>,std::allocator<char> > refvecFiles="c:\\boost\\multiprecision\\traits\\", bool bSearchSubdirectories=false) Line 113 C++
File Lister 6.0.exe!SearchDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > FileSearch="\*", std::basic_string<char,std::char_traits<char>,std::allocator<char> > refvecFiles="c:\\boost\\multiprecision\\detail\\", bool bSearchSubdirectories=false) Line 113 C++
File Lister 6.0.exe!SearchDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > FileSearch="\*", std::basic_string<char,std::char_traits<char>,std::allocator<char> > refvecFiles="c:\\boost\\multiprecision\\cpp_int\\", bool bSearchSubdirectories=false) Line 113 C++
File Lister 6.0.exe!SearchDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > FileSearch="\*", std::basic_string<char,std::char_traits<char>,std::allocator<char> > refvecFiles="c:\\boost\\multiprecision\\concepts\\", bool bSearchSubdirectories=false) Line 113 C++
отладчик останавливается в ostream на
if (_State == ios_base::goodbit
&& _Ostr.rdbuf()->sputn(_Val, _Count) != _Count)
_State |= ios_base::badbit;
Люди продолжают добавлять тег C++ для ваших C++ 11 вопросов. Пожалуйста, примите намек! –
Если вы столкнулись с крахом, первое, что вам нужно сделать, это запустить вашу программу в отладчике и позволить отладчику поймать крах в действии. Это скажет вам, где * произошел сбой, и вы сможете проверить стек вызовов функций и перейти к его коду (если отладчик не останавливается в вашем коде уже), а затем вы можете проверить значения всех переменных. По крайней мере, вы должны отредактировать свой вопрос, чтобы показать нам местоположение * в вашем коде * аварии и предпочтительно значения задействованных переменных. –
Возможный дубликат [Как вы повторяете каждый файл/каталог рекурсивно в стандартном C++?] (Http://stackoverflow.com/questions/67273/how-do-you-iterate-through-every-file-directory-recursive -в-стандарт-с) –