How to search a string in a text file without loading it to memory? I need a function that seeks directory to the file.

Anybody here knows how to search a string in a text file without loading it memory such as using TStringList, TStringStream, etc? It would be greatful if somebody could give me example(s).

Thanks,
Edwin
edwinaceronAsked:
Who is Participating?
 
kretzschmarConnect With a Mentor Commented:
a high performant search using a 64kb (as docu desciribes) memory map range, usefull for really large files (> 1MB up to 4GB),
if you have lesser files -> use a tsringlist and the pos function)

from my paq:

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20698441.html

---- paste accepted answer

well, was long time ago :-))

found another unit, which encapsulates memory mapped files:
(from Dmitry Streblechenko)

http://www.programmersheaven.com/d/click.aspx?ID=F2883

there are two changes to do in this unit-source

- unit-name didn't match filename
- and one EFCreateError.Create(... must be changed to EFCreateError.CreateFmt(...

did done this sample

unit mmstream_test_u;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    ListBox1: TListBox;
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
uses mmStream;

var mmf : TMemoryMappedFileStream;

//BinPosEx from Madshi
function BinPosEx(subStr,str: pchar; fromPos,toPos,  subStrLen,strLen: cardinal) : cardinal; assembler
asm      //       EAX    EDX         ECX     [ESP+16][ESP+12]  [ESP+8]               EAX
       TEST    EAX,EAX                  // subStr empty ?
       JE      @@noWork
       TEST    EDX,EDX                  // str empty ?
       JE      @@fail4
       TEST    ECX,ECX                  // fromPos = 0 ?
       JE      @@fail4
       PUSH    EBX
       MOV     EBX,ECX                  // EBX = fromPos
       MOV     ECX,[ESP+20]             // ECX = toPos  (+4 w/ PUSH EBX)
       TEST    ECX,ECX                  // toPos = 0 ?
       JE      @@fail3
       PUSH    ESI
       PUSH    EDI
       MOV     ESI,EAX                  // ESI = substr
       MOV     EDI,EDX                  // EDI = str
       CMP     EBX,ECX                  // fromPos > toPos ?
       JA      @@backwards
@@forwards:
       MOV     EDX,[ESP+20]             // EDX = strLen  (+12 w/ PUSH EBX+ESI+EDI)
       CMP     EBX,EDX                  // fromPos > Length(str) ?
       JA      @@fail2
       CMP     ECX,EDX                  // toPos <= Length(str) ?
       JNA     @@toPosOk
       MOV     ECX,EDX                  // toPos = Length(str)
@@toPosOk:
       MOV     EDX,[ESP+24]             // EDX = subStrLen  (+12 w/ PUSH EBX+ESI+EDI)
       DEC     EDX                      // EDX = Length(substr) - 1
       JS      @@fail2                  // EDX < 0 ?
       PUSH    EDI                      // remember str position to calculate index
       DEC     EBX                      // dec(fromPos)
       ADD     EDI,EBX                  // "Delete (str, 1, fromPos - 1)"
       SUB     ECX,EBX                  // toPos := toPos - fromPos + 1
       SUB     ECX,EDX                  // #positions in str to look at = Length(str) - Length(substr) + 1
       JBE     @@fail1                  // #positions <= 0 ?
       MOV     AL,[ESI]                 // AL = first char of substr
       INC     ESI                      // Point ESI to 2'nd char of substr
@@fwLoop:
       REPNE   SCASB
       JNE     @@fail1
       MOV     EBX,ECX                  // save outer loop counter
       PUSH    ESI                      // save outer loop substr pointer
       PUSH    EDI                      // save outer loop str pointer
       MOV     ECX,EDX
       REPE    CMPSB
       POP     EDI                      // restore outer loop str pointer
       POP     ESI                      // restore outer loop substr pointer
       JE      @@fwFound
       MOV     ECX,EBX                  // restore outer loop counter
       JMP     @@fwLoop
@@fwFound:
       POP     EDX                      // restore pointer to first char of str
       MOV     EAX,EDI                  // EDI points of char after match
       SUB     EAX,EDX                  // the difference is the correct index
       POP     EDI
       POP     ESI
       POP     EBX
       JMP     @@noWork
@@backwards:
       MOV     EDX,[ESP+20]             // EDX = strLen  (+12 w/ PUSH EBX+ESI+EDI)
       CMP     ECX,EDX                  // toPos > Length(str) ?
       JA      @@fail2
       CMP     EBX,EDX                  // fromPos <= Length(str) ?
       JNA     @@fromPosOk
       MOV     EBX,EDX                  // fromPos = Length(str)
@@fromPosOk:
       MOV     EDX,[ESP+24]             // EDX = subStrLen  (+12 w/ PUSH EBX+ESI+EDI)
       DEC     EDX                      // EDX = Length(substr) - 1
       JS      @@fail2                  // EDX < 0 ?
       MOV     EAX,EDI                  // remember str position to calculate index
       ADD     EAX,EDX                  // add backwards calculation
       SUB     EAX,2
       PUSH    EAX
       DEC     ECX                      // dec(toPos)
       ADD     EDI,ECX                  // "Delete (str, 1, toPos - 1)"
       SUB     EBX,ECX                  // fromPos := fromPos - toPos + 1
       MOV     ECX,EBX                  // swap (fromPos, lastPos)
       ADD     EDI,ECX
       DEC     EDI
       ADD     ESI,EDX
       SUB     ECX,EDX                  // #positions in str to look at = Length(str) - Length(substr) + 1
       JBE     @@fail1                  // #positions <= 0 ?
       MOV     AL,[ESI]                 // AL = first char of substr
       DEC     ESI                      // Point ESI to 2'nd char of substr
       STD
@@bwLoop:
       REPNE   SCASB
       JNE     @@fail0
       MOV     EBX,ECX                  // save outer loop counter
       PUSH    ESI                      // save outer loop substr pointer
       PUSH    EDI                      // save outer loop str pointer
       MOV     ECX,EDX
       REPE    CMPSB
       POP     EDI                      // restore outer loop str pointer
       POP     ESI                      // restore outer loop substr pointer
       JE      @@bwFound
       MOV     ECX,EBX                  // restore outer loop counter
       JMP     @@bwLoop
@@bwFound:
       POP     EDX                      // restore pointer to first char of str + backwards calculation
       MOV     EAX,EDI                  // EDI points of char after match
       SUB     EAX,EDX                  // the difference is the correct index
       CLD
       POP     EDI
       POP     ESI
       POP     EBX
       JMP     @@noWork
@@fail0:
       CLD
@@fail1:
       POP     EDX                      // get rid of saved str pointer
@@fail2:
       POP     EDI
       POP     ESI
@@fail3:
       POP     EBX
@@fail4:
       XOR     EAX,EAX
@@noWork:
end;


procedure TForm1.Button1Click(Sender: TObject);
var
 sl : TstringList;
 P : PChar;
 i,l : Integer;
begin
 P := Nil;
 if Opendialog1.Execute then
 begin
   try
     sl := TstringList.Create;
     mmf := TMemoryMappedFileStream.Create(OPendialog1.Filename,'',fmOpenReadWrite);
     l := length(edit1.text);
     P := PChar(edit1.text);
     i := 0;
     repeat
       i := BinPosEx(P,PChar(mmf.memory),i+1,mmf.size,l,mmf.size);
       if i > 0 then sl.Add(inttostr(i));
     until i = 0;
     Listbox1.Items.Assign(sl);
   finally
     mmf.Free;
     sl.free;
   end;
 end;
end;

end.

atleast you should visit madshi's site
www.madshi.net

and get the mad..-librarys there

---------- paste end

meikl ;-)
0
 
meceCommented:
got some errors at mmstream.pas
why ??
0
 
kretzschmarCommented:
see above

there are two changes to do in this unit-source

- unit-name didn't match filename
- and one EFCreateError.Create(... must be changed to EFCreateError.CreateFmt(...

0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
meceCommented:
good example,
thanx
0
 
kretzschmarCommented:
to edwinaceron,
does it help?
any questions about this?
0
 
kretzschmarCommented:
to edwinaceron,
are you still alive?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.