Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Scan File System without opening Files

Status
Not open for further replies.

areric

Programmer
Jul 13, 2003
47
US
Hey all,

Im trying to recursively scan a file system obtaining information like file name, file size, access dates, etc. Im using windows api to do this using the FindFirstFile and FindNextFile functions to scan through directories.

These functions open a file handle which acts like an open file to the operating system. When i scan a large number of files i end up with a ton of open files and i dont close the handle until the directory is done so in some cases i run out of available open files (windows has a limit) Additionally no one can use the files i have scanned until i close them.

Does anyone know a way i can recursively scan an directory without opening the files?


Thanks.

p.s. my old code is below
Code:
void scanPath(string path, WIN32_FIND_DATA &fileData) 
{
	vector <string> dirs;
	string dirName;
	string pathToScan;
	HANDLE searchHandle;
	string acctName;
	string filename;

	pathToScan = combinePath(path, "*");
	//cout<<path<<endl;
	

	searchHandle = FindFirstFile(pathToScan.c_str(), &fileData);
	//cout<<"after search handle"<<endl;
	while (FindNextFile(searchHandle, &fileData))
	{
		if (strcmpi (fileData.cFileName, ".") != 0 &&
            strcmpi (fileData.cFileName, "..") != 0)
		{
			//cout<<"In While"<<endl;
			if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
				dirs.push_back(fileData.cFileName);
			}
			filename = combinePath(path, fileData.cFileName);
			//getOwnerName(filename.c_str(), acctName);
			GetOwner(filename.c_str(), acctName);
			cout<<path<<"\\"<<fileData.cFileName<<","<<acctName<<endl;			
		}
	}
	FindClose(searchHandle);

	for (int i=0; i<dirs.size(); i++)
	{
	//	cout<<"recursing"<<endl;
		dirName = dirs[i];
		scanPath(path+"\\"+dirName, fileData);
	}
}
 
As far as I know FindFirst/FindNext dir scanning does not open any file handles. See GetOwner() function (I can't find corresponding Windows API file management function).
Don't forget to test searchHandle after FindFirstFile()...
 
I have used the code below to find a file ( fileToFind ) anywhere in a starting directory, it will search through all sub directorys until it finds the said file and it returns the directory that the file is in (or "none" ) if it cant find it.

I'm sure you can take this code and modify it to do what you want it to?

Note: This does NOT open the files and I have had it search through about 30000+ files to find the said file.



Code:
CString FileIO::FindFile ( LPCTSTR baseDirectory, CString fileToFind )
{
  CFileFind finder;
  
  resultsDir = "none";  // used to check if file has not been found.
   // build a string with wildcards
  CString strWildcard( baseDirectory );
  strWildcard += _T( "\\*.*" );

  // start working for files

  BOOL bWorking = finder.FindFile( strWildcard );

  while (bWorking)
  {
    bWorking = finder.FindNextFile();

    // skip . and .. files; otherwise, we'd recursively search infinitely!
    if ( finder.IsDots() ) continue;

    CString str = finder.GetFilePath();
    // if change dir name so has first run no in it - we can change the search criteria
    
    // if it's a directory, recursively search it
    if ( finder.IsDirectory() )
    {
      if ( FindFile( str, fileToFind ) != "none" ) bWorking = false; // if FindFile != "none" -> file has been found - so exit
    }
    else 
    {
      if ( finder.GetFileName() == fileToFind ) 
      { 
        bWorking = false; 
        resultsDir = finder.GetFilePath();
      }
    }
  }
  finder.Close();
  return ( resultsDir );
}

Hope it helps, and good luck!!!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top