Scanning harddrives (Order problem)

Started by
5 comments, last by Xero-X2 20 years, 8 months ago
I have writtin a function that will scan thought all directories and sub directories and record all files into a big text file. later it will be used to look for files of a certain type. like *.bmp.. but for the moment it finds every thing. I useed FindNextFile/FindFirstFile. it works great except for one problem, when it comes to scanning each drive, the order in which I scan them will cause problems

c:\ works
d:\ fails
e:\ fails
_________
c:\ works
e:\ fails
d:\ fails
_________
d:\ works
c:\ works
e:\ fails
_________
d:\ works
e:\ fails
c:\ works

but

e:\ works
d:\ works
c:\ works
 
why would I have to scan the drives in reverse order? why can''t i scan from c:\ down to the last drive? can anyone lend me some insight into this problem? "I seek knowledge and to help those who also seek it"
"I seek knowledge and to help those who also seek it"
Advertisement
http://www.chiark.greenend.org.uk/~sgtatham/bugs.html
What? Im saying that I can only scan the drives in reverse order, if I try forward order it gives me the error ERROR_FILE_NOT_FOUND. but when I do it backwards it gives no errors and succsessfully compiles the list.

Does anyone know what could cause this?
"I seek knowledge and to help those who also seek it"
AP is trying to say you did not give enough information. You should post some code so we can see how you are calling FindNextFile. But, I understand your question. There are bugs with FindNextFile especially in how it deals with long filenames. Sorry I don''t know the exact nature of the bugs, but they can cause FindNextFile can return ERROR_FILE_NOT_FOUND for no apparent reason sometimes. You should not check for ERROR_FILE_NOT_FOUND when using FindNextFile. Just check to see if it returns a non zero value (this is in the MSDN docs). But, I am just guessing since I don''t know how you actually have it coded.
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
UINT dirs;UINT files;void Scan(char* Dir){WIN32_FIND_DATA data;HANDLE Hdir= FindFirstFile(Dir,&data);for (int s=0; s<260; s++)if (Dir[s]==''*'' || Dir[s]==''.'')Dir[s]=0;char addFiles[260];if (Hdir != INVALID_HANDLE_VALUE){if (data.cFileName[0] != ''.'')if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ){dirs++;sprintf(addFiles,"%s%s\\*.*",Dir,data.cFileName);Scan(addFiles);}else{files++;}}else{FindClose(Hdir);return;}while (1){if (FindNextFile(Hdir,&data)){if (data.cFileName[0] != ''.'')if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ){dirs++;sprintf(addFiles,"%s%s\\*.*",Dir,data.cFileName);Scan(addFiles);}else{files++;}}elsebreak;}FindClose(Hdir);}


that is the code that scans and records total dirs, and files.
I run it based each drive
Scan("C:\\*.*");Scan("D:\\*.*");Scan("E:\\*.*"); 


It won''t read a drive that comes after one that is already read.
and it won''t read the same drive twice.

Any help would be appretaited.

"I seek knowledge and to help those who also seek it"
"I seek knowledge and to help those who also seek it"
I doubt your problem is related to bugs in Find* functions. You can try my code if you'd like:

#include <windows.h>#include <crtdbg.h>#include <tchar.h>#include <string>#include <queue>#include <iostream>// Macros so we can use both MBCS and UNICODE#ifdef _UNICODEtypedef std::wstring String;#define Cout std::wcout#elsetypedef std::string String;#define Cout std::cout#endif#ifdef _DEBUG#define _VERIFY _ASSERT#else#define _VERIFY(x) (x)#endifstatic DWORD g_count = 0;static void OnFoundFile(const String& currentRoot, const WIN32_FIND_DATA& FindData){//	Cout << currentRoot << _T('\\') << FindData.cFileName << std::endl;	++g_count;}static void WalkPath(LPCTSTR szRootDir, LPCTSTR szSearchPattern){	// We do an iterative algorithm, therefore we keep a queue	// of directories to search through. We looop through	// everything we find. If we find a directory, add it	// to that queue.	// Then all we need to do is to keep searching directories	// until that queue is empty, in which case we're ready.	// Seed in the queue is the directory the user gave to	// this function.	std::queue DirectoriesToWalk;	DirectoriesToWalk.push(szRootDir);	// Used for FindFirstFile, re-use the string for performance	String FileName;	while ( !DirectoriesToWalk.empty() )	{		// take a directory to search from the queue		const String CurrentRoot = DirectoriesToWalk.front();		DirectoriesToWalk.pop();		FileName.clear();		FileName += CurrentRoot;		FileName += szSearchPattern;		WIN32_FIND_DATA FindData;		HANDLE hFind   = ::FindFirstFile(FileName.c_str(), &FindData);		BOOL Continue = (hFind != INVALID_HANDLE_VALUE);		while (Continue)		{			if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)			{				if (FindData.cFileName[0] != _T('.'))				{					// We found another directory, add it to the pile					//  of directories to search through.					std::string DirToAdd(CurrentRoot);					DirToAdd += FindData.cFileName;					DirToAdd += _T('\\');//					Cout << "Adding dir to search: " << DirToAdd << std::endl;					DirectoriesToWalk.push(DirToAdd);				}			}			else			{				// This wasn't a directory.				OnFoundFile(CurrentRoot, FindData);			}			// See if there's anything left in here.			Continue = FindNextFile(hFind, &FindData);		}		if (hFind != INVALID_HANDLE_VALUE)		{			_VERIFY(FindClose(hFind));		}	}}void _tmain(){	WalkPath( _T("C:\\Temp\\"), _T("*") );	Cout << "Number of files: " << g_count << std::endl;}  


[edited by - developer on August 7, 2003 6:37:43 PM]
Thanks, I''ll give it a try.

"I seek knowledge and to help those who also seek it"
"I seek knowledge and to help those who also seek it"

This topic is closed to new replies.

Advertisement