I wrote an app to find all occurrences of a string in a bunch of files - I wrote this because a bug in UltraEdit caused it's find-in-files to fail. That bug is still there but pre-bug, UltraEdit could process a bunch of files very quickly - though not as fast as NotePad++.
As-is, my app does what I need. It's a bit more flexible than the built-in functions of UE and NP++ too. It is, however, much slower. Below is a stand-alone code snippet (use your own test file and test search string). Not representative of the app but using the exact string search loop - the same loop I use in other util apps:
Code: Select all
EnableExplicit
#FileIO = 0
Structure StrList
sPath.s
sFile.s
sLnum.s
sStrf.s
EndStructure
Global NewList gStrFound.StrList() ;Info displayed in a ListIcon, User can delete selected rows
Global igFormat.i = 0
Global qgFileLen.q = 0
Global *gTextBuff
Global sgEol.s = #CRLF$
Global dgStartTime.d, dgElapsedTime.d
Procedure PfFindString()
;#----------------------
;example find "Sleep"
Protected qStart.q, qLen.q
Protected sFindStr.s = "Sleep"
Protected iPosn.i, iLine.i, iFound.i
Protected sLine.s
SetPriorityClass_(GetCurrentProcess_(), #HIGH_PRIORITY_CLASS) ;#ABOVE_NORMAL_PRIORITY_CLASS)
;ForEach gFilesList() ;bunch of files already filtered as containing the string
If ReadFile(#FileIO, "C:\MyTextFile.txt")
igFormat = ReadStringFormat(#FileIO)
qgFileLen = Lof(#FileIO)
If(qgFileLen > 0)
*gTextBuff = AllocateMemory(qgFileLen)
ReadData(#FileIO, *gTextBuff, qgFileLen)
CloseFile(#FileIO)
;On average (29 .cpp files in test, filtered to 12)
;this search loop takes about 1.4 seconds per file (compiled exe);
;17 seconds to process all files. Typical file 1000 - 3000 lines, 2 to 12 hits
;NotePad++ processes all the files in just 1 second
dgStartTime = ElapsedMilliseconds()
qStart = 1 : iLine = 0 : qLen = 0
Repeat
iPosn = FindString(PeekS(*gTextBuff, qgFileLen, igFormat), sgEol, qStart, #PB_String_NoCase)
If(iPosn > 0)
sLine = Mid(PeekS(*gTextBuff, qgFileLen, igFormat), qStart, (iPosn - qStart))
qStart = iPosn + Len(sgEol)
iLine = iLine + 1
iFound = FindString(sLine, sFindStr, 1, #PB_String_NoCase)
If(iFound > 0)
AddElement(gStrFound())
;gStrFound()\sPath = GetPathPart(gFilesList())
;gStrFound()\sFile = GetFilePart(gFilesList())
gStrFound()\sLnum = Str(iLine)
gStrFound()\sStrf = Trim(sLine)
Debug gStrFound()\sLnum + " " + gStrFound()\sStrf
EndIf
EndIf
Until(iPosn = 0)
dgElapsedTime = ElapsedMilliseconds() - dgStartTime
Debug dgElapsedTime / 1000
EndIf
EndIf
;Next
SetPriorityClass_(GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS)
EndProcedure
PfFindString()
End
I was expecting this method to be faster than it is, though it is OK, I can of course wait 20 seconds for the results. Is it the best way though? Is there a faster way to find every occurrence of the string and capture the line and line number?