Solved

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

Posted on 2003-11-18
6
285 Views
Last Modified: 2010-04-03
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
0
Comment
Question by:edwinaceron
  • 4
  • 2
6 Comments
 
LVL 27

Accepted Solution

by:
kretzschmar earned 250 total points
ID: 9769860
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
 

Expert Comment

by:mece
ID: 9770246
got some errors at mmstream.pas
why ??
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9770261
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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

Expert Comment

by:mece
ID: 9771133
good example,
thanx
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9777166
to edwinaceron,
does it help?
any questions about this?
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9796437
to edwinaceron,
are you still alive?
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi cmd execution 6 60
FMX enumerated colours 2 99
Show Listview image from database (String field) 5 124
CheckListBox usage 3 58
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …

770 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