Thread View: borland.public.cppbuilder.nativeapi
4 messages
4 total messages
Started by mataus
Tue, 30 Oct 2007 20:54
find .exe's
Author: mataus
Date: Tue, 30 Oct 2007 20:54
Date: Tue, 30 Oct 2007 20:54
57 lines
2398 bytes
2398 bytes
Hi all,
I need code to find all .exe file on a disk. I use FindFirstFile /
FindNextFile and it works but it seems slow. When i run code its time is
long (1 min 30 secs for ~2500 files on T60 thinkpad ). However, if i use
command line cmd->dir *.exe /s - time is fast (10 secs for ~2500 on T60).
Can anyone help me make this fast?
My code is:
void TForm1::RecursiveSearch(const AnsiString &p_sPath)
{
bool bNext;
HANDLE hFileSearching;
WIN32_FIND_DATA fdFindFileData;
AnsiString sPath = p_sPath;
if (!sPath.IsPathDelimiter(sPath.Length()))
sPath = AnsiString(sPath + "\\");
sPath = AnsiString(sPath + "*");
hFileSearching = FindFirstFile(sPath .c_str(), &fdFindFileData);
// If the handle is valid, process it
if (bNext = (hFileSearching != INVALID_HANDLE_VALUE))
{
AnsiString szFile;
do
{
// Call self if it finds directory
if ((FILE_ATTRIBUTE_DIRECTORY & fdFindFileData.dwFileAttributes) &&
strcmp(fdFindFileData.cFileName,".") &&
strcmp(fdFindFileData.cFileName,".."))
{
RecursiveSearch(ExtractFilePath(sPath) +
fdFindFileData.cFileName);
}
szFile = (AnsiString)fdFindFileData.cFileName;
if (ExtractFileExt(szFile)==".exe")
{
Memo1->Lines->Add(szFile);
}
// Process next file...
bNext = FindNextFile(hFileSearching, &fdFindFileData);
Application->ProcessMessages();
}
while (bNext);
}
FindClose(hFileSearching);
}
thanks - mataus
Re: find .exe's
Author: Remy Lebeau (TeamB)
Date: Tue, 30 Oct 2007 20:48
Date: Tue, 30 Oct 2007 20:48
61 lines
2835 bytes
2835 bytes
"mataus" <mataus@gmail.com> wrote in message
news:4727891b$1@newsgroups.borland.com...
> My code is:
For every directory, you are checking for a file extension. Don't do that.
You are also calling ProcessMessages() on every iteration of the loop, which
will drastically slow down the code as well.
Try something more like the following instead:
int MsgUpdateCnt = 0;
void __fastcall TForm1::RecursiveSearch(const AnsiString &p_sPath)
{
MsgUpdateCnt = 0;
InternalRecursiveSearch(p_sPath);
}
void __fastcall TForm1::InternalRecursiveSearch(const AnsiString
&p_sPath)
{
AnsiString sPath = IncludeTrailingBackslash(p_sPath);
WIN32_FIND_DATA fdFindFileData;
HANDLE hFileSearching = FindFirstFile((sPath + "*").c_str(),
&fdFindFileData);
if( hFileSearching != INVALID_HANDLE_VALUE )
{
do
{
if( FILE_ATTRIBUTE_DIRECTORY &
fdFindFileData.dwFileAttributes )
{
if( (strcmp(fdFindFileData.cFileName, ".") != 0) &&
(strcmp(fdFindFileData.cFileName, "..") != 0) )
InternalRecursiveSearch(sPath +
fdFindFileData.cFileName);
}
else
{
AnsiString szFile = fdFindFileData.cFileName;
if( AnsiSameText(ExtractFileExt(szFile), ".exe") )
Memo1->Lines->Add(szFile);
}
if( ++MsgUpdateCnt == 100 )
{
Application->ProcessMessages();
MsgUpdateCnt = 0;
}
}
while( FindNextFile(hFileSearching, &fdFindFileData) );
FindClose(hFileSearching);
}
}
Gambit
Re: find .exe's
Author: Bob Gonder
Date: Tue, 30 Oct 2007 21:14
Date: Tue, 30 Oct 2007 21:14
29 lines
2115 bytes
2115 bytes
mataus wrote: >Can anyone help me make this fast? 1) You use AnsiString which is often slower than plain cstrings. 2) You Add() to Memo->Lines. This is probably slow. 3) You manually check _every_ file to see if it is a folder or an exe. 4) You ProcessMessages() way too often. 5) You are passed the path which you then mess with and later ExtractFilePath(sPath) to get back to the passed path. For #1, Don't be so quick to use AnsiString all over the place. Use a char array[MAX_PATH+1] for local strings. For #2, Append() might be faster. BeginUpdate / EndUpdate around the entire process might speed up the Memo. For #3, I would break it into two sections. First section, FindFirst/Next would specify FILE_ATTRIBUTE_DIRECTORY in the search attributes. (Handle all folders first, quickly.) Second section, new FindFirst/Next would specify \*.exe so you only get those files instead of _every_ file. For #4, eliminate it from the loop. If you find you really do need it, then put a counter on it so it only executes every ~50 times through the loop. For #5, you could copy the passed path to a local char[] and ensure it has the terminating \. Then use that to build the other strings.
Re: find .exe's
Author: JohnC
Date: Tue, 30 Oct 2007 22:17
Date: Tue, 30 Oct 2007 22:17
16 lines
1586 bytes
1586 bytes
Have you tried something along these lines?
WinExec("cmd /c \"dir *.exe /s > test.txt\"", SW_HIDE);
John
"mataus" <mataus@gmail.com> wrote in message
news:4727891b$1@newsgroups.borland.com...
> Hi all,
>
> I need code to find all .exe file on a disk. I use FindFirstFile /
> FindNextFile and it works but it seems slow. When i run code its time is
> long (1 min 30 secs for ~2500 files on T60 thinkpad ). However, if i use
> command line cmd->dir *.exe /s - time is fast (10 secs for ~2500 on T60).
> Can anyone help me make this fast?
>
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads