Solved

Folder Scan - GCC Compatible

Posted on 2009-07-15
9
467 Views
Last Modified: 2013-12-14
Hi experts,

In the distant past, I got some great help with a recursive directory scan function - see link.

http://www.experts-exchange.com/Programming/Languages/CPP/Q_24391623.html

 Since then however, we have a requirement that the c++ application will sit server side and  thus will not be able to use windows data structures as part of the solution.

What i need is to return a container of filepaths that contain a keyword that is passed to the scanning function. So for example:

If the server contains the following files in the root directory:
file123.dat
file1234.dat
file1111.dat
file111122.dat

and i call the scanning function with the keyword "123":
path_array=filescan("123",root_path):

The i would have the complete filepaths for the following files returned in the path_array[]

file123.dat
file1234.dat

Any help would be appreciated.

Thanks
0
Comment
Question by:simondopickup
9 Comments
 
LVL 14

Expert Comment

by:flob9
ID: 24859122
Instead of passing to "findfirstfile" fullpath + "*.*", give it :

fullpath + "*"+keyword+"*.*"

where fullpath is your current search directory, and keyword "123"

file1234.dat and file123.dat will match pattern *123*.*
0
 
LVL 14

Expert Comment

by:flob9
ID: 24859167
... depending on how your "filescan" function is implemented, this can filter on directory too.
Please show us your current filescan code.
0
 

Author Comment

by:simondopickup
ID: 24859222
You have it in the link.

I cant have the solution have at the minute and stick it server side. It wont work. I need to remove all windows headers.
0
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 
LVL 14

Expert Comment

by:flob9
ID: 24859444
Just pass your keyword parameter to the WlakTree and HandleFile like this :
#include <windows.h> 
#include <conio.h> 
#include <time.h> 
#include <stdio.h> 
#include <string> 
#include <iostream> 
#include <fstream> 
 
using namespace std;
 
static int FileCount=0;									// Initialise parse counter to 0.
void HandleFile (WIN32_FIND_DATA *file_data, char* Keyword);			// Declarator to handle file function
void WriteToLog (string Message);						// Declarator for the WritetoLog function							
void WalkTree (char *Path, char *Base, char* Keyword);					// Declarator to the WalkTree Function
 
 
int main()											
{ 
char *filebase = "C:\\Temp\\";  
char *filepath = "";
char *keyword = "Plan";
 
char MessageBuffer[100];
char datebuf[9];												// stores the date obtained from _strdate() 
char timebuf[9];												// stores the time obtained from _strtime() 
string CurDate = _strdate(datebuf);								// get current date for log information
string CurTime = _strtime(timebuf);								// get current time for log information
string LogMessage; 
int i;
 
WalkTree(filepath,filebase,keyword);									// Start the process of scanning from the filebase above
 
if (FileCount > 0)
{ 
	i =  sprintf(MessageBuffer, "Total files parsed = %d", FileCount); 
	i =+ sprintf(MessageBuffer + i," %s %s\n", CurDate.c_str(), CurTime.c_str()); 
	LogMessage = MessageBuffer; 
	WriteToLog(LogMessage); 
} 
else
{
	i =  sprintf(MessageBuffer, "No files parsed"); 
	i += sprintf(MessageBuffer + i,"  (%s %s)\n", CurDate.c_str(), CurTime.c_str()); 
	LogMessage = MessageBuffer; 
	WriteToLog(LogMessage); 
}
 
return 0; 
}
 
void WalkTree (char *Path,char *Base, char* Keyword)
{
	WIN32_FIND_DATA FindDat;
	HANDLE FndHnd;
	DWORD dwAtt;
	char acPath[MAX_PATH] ;
	char acBase[MAX_PATH] ;
	 
	printf ( "WalkTree()was called with <%s> <%s>\n",Path,Base);		// Print Output that walktree was called with the path and base
	 
	//if ( lstrcmp(".",Path)==0 ||  lstrcmp("..",Path)==0)							// If last character of path is a '.' then return <--- WHY IS THIS HERE?!?!?!
	//	return;
	 
	if(Base)															// Do if Base is occupied with characters
	sprintf (acPath, "%s\\%s",Base,Path);								// If base path exists then append base and path to acpath buffer
	else
	lstrcpy (acPath, Path);												// Make acPath buffer a copy of Path should Base be empty
	 
	printf ( "path is %s\n",    acPath);								// Print the path to the output										
	lstrcpy (acBase, acPath);											// Make acBase the current path
		
	dwAtt = GetFileAttributes (acPath);									// Get file attributes of the new path
	 
	if ( 0xffffffff == dwAtt)											// If the path can not be found then signal an error and write to log.
	{
	 // Write an error to the log here
	}
	 
	if (FILE_ATTRIBUTE_DIRECTORY & dwAtt)								// If NEW path is a directory
	{
		if  ( '\\'== acPath[lstrlen(acPath)-1])							// If the end 2 characters of acPath are '\\' then
		{lstrcat (acPath, "*.*");}										// append a *.* to the end of the filepath to indicate a path for all files
		else
		{lstrcat(acPath, "\\*.*");}										// or this to ensure filepath for acpath ends in \\*.*
		printf ( "path is now %s\n",acPath);							// print the new file path to the output device.
	}
	 
	FndHnd = FindFirstFile(acPath, &FindDat);							// Now look for the first file in the new file path. 
	 
	if (INVALID_HANDLE_VALUE == FndHnd)									// If no handle is found - or no files at all then throw an error
	{
	 // Write an error to the log here
	printf ("ERROR %d\n",GetLastError());								// Error Printed and returned
	return;
	}
	 
	if ( FILE_ATTRIBUTE_DIRECTORY == FindDat.dwFileAttributes)			// IF the FindFirstFile FINDS a directory check (different from 
	{																	// deciphering if the current path is a directory (above)
		if ( !lstrcmp(FindDat.cFileName,".")==0 &&  !lstrcmp(FindDat.cFileName,"..")==0)
			WalkTree (FindDat.cFileName,acBase,Keyword);							// Pass the filename of the handle to the top of the function to redefine the path for the search
	}
	else
	 HandleFile (&FindDat,Keyword);												// If file found, pass to the handler ( the IF function to examine the name
																		// and to enter into the logs. 
	while ( FindNextFile(FndHnd, &FindDat))
	{
		if ( FILE_ATTRIBUTE_DIRECTORY == FindDat.dwFileAttributes)		// IF the FindNextFile FINDS a directory check (different from
		{				
			if ( lstrcmp(FindDat.cFileName,".")==0 ||  lstrcmp(FindDat.cFileName,"..")==0)
				continue;
			WalkTree (FindDat.cFileName,acBase,Keyword);							// then recurse the walk tree function 						
		}
		else
		  HandleFile (&FindDat,Keyword);										// If FILE_ATTRIBUTE_DIRECTORY is not equal to FileAttributes then you have 
	}																	// found a viable file - so handle it.
	 
	if ( ERROR_NO_MORE_FILES != GetLastError())
	{
	 // error
	}
	FindClose (FndHnd);
}
 
void HandleFile (WIN32_FIND_DATA *file_data, char* Keyword)						// Pass the win32_find_data structure by reference
{																	// to the log if the name viable against the check.
  string keyword = Keyword;											// keyword to check each handle file before opening.
  char datebuf[9];													// stores the date obtained from _strdate() 
  char timebuf[9];													// stores the time obtained from _strtime() 
  char MessageBuffer[100];											// holds the message which is converted into a string
  string LogMessage;												// holds the converted message to be written in the log
  string file_name = file_data->cFileName;
  string CurDate = _strdate(datebuf);								// get current date for log information
  string CurTime = _strtime(timebuf);								// get current time for log information
  int sc,i;															// holds result of search term and character count
 
 
 
		sc=	file_name.find(keyword);								// Check for the correct string 'audio' within the filename			
		if(sc!=-1)													// If sc returned -1, then the string has not been found				
		{ 
		//Add the filename to the vector list and write to log that this has happened
		FileCount++;
		}	// end of if
		else
		{
		string fileprint =file_name;
		i =  sprintf(MessageBuffer, "Following file was not opened: %s", fileprint.c_str());
		i += sprintf(MessageBuffer + i,"  %s %s", CurDate.c_str(), CurTime.c_str());
		i += sprintf(MessageBuffer + i,"  Number of characters are %d\n", i);
		LogMessage = MessageBuffer; 
		WriteToLog(LogMessage); 
		}	// end of else
	return;
	} 
 
void WriteToLog(string Message)						// This a function that writes to the log whenever the WritetoLog function is called
{ 
string UtilityLog  = "C:\\Temp\\AudioParseLog.txt"; 
ofstream WriteFile; 
WriteFile.open(UtilityLog.c_str(), ios::app);		// Open the log file to write the input and append to the end of the file
if(WriteFile.fail())								// If the opening of the parselg fails then throw a message box to the user
{ 
	MessageBox(NULL,"Error writing to AudiParseLog!  Contact Support.", 
	   "ParsingInfo", MB_OK | MB_ICONERROR);
	return;
} 
else
{WriteFile << Message;}
WriteFile.close(); 
return; 
} 

Open in new window

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 24859592
>>>I need to remove all windows headers.

Do you mean you are targeting another operating system eg. UNIX on the server ?
0
 

Author Comment

by:simondopickup
ID: 24859655
Do you mean you are targeting another operating system eg. UNIX on the server ?
>>exactly
0
 
LVL 14

Expert Comment

by:flob9
ID: 24859723
findfirstfile and other functions you use are windows specific ... you will need to write it another way from scratch.
0
 
LVL 14

Accepted Solution

by:
flob9 earned 250 total points
ID: 24859759
You can use opendir and readdir under linux.
0
 
LVL 12

Assisted Solution

by:Let_Me_Be
Let_Me_Be earned 250 total points
ID: 24860040
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question