1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| function SearchStringInFile(const FileName: string; SearchString: string; out OffSets: TIntegerDynArray; KeepOffSet: Boolean = False; CaseSensitive: Boolean = True): Integer;
const
BUF_SIZE: Integer = 1024;
var
FileToSearch: file;
SearchBuf: array of Char;
iSearchBufPos, iSearch, iMark, iCountFound, iRememberFound, iReaded: Integer;
SearchLen: Integer;
AmtTransferred: Integer;
FileModeCopy: Byte;
begin
Result := 0;
iReaded := 0;
SetLength(SearchBuf, BUF_SIZE);
SearchLen := Length(SearchString);
if not CaseSensitive then
SearchString := SysUtils.UpperCase(SearchString);
FileModeCopy := FileMode;
FileMode := SysUtils.fmOpenRead;
try
AssignFile(FileToSearch, FileName);
Reset(FileToSearch, 1);
try
iCountFound := 0;
while not Eof(FileToSearch) do
begin
BlockRead(FileToSearch, SearchBuf[0], BUF_SIZE, AmtTransferred); // [0] parce que c'est un tableau dynamique
iRememberFound := iCountFound;
iSearchBufPos := 0;
while iSearchBufPos < AmtTransferred do
begin
// Comparaison Octet par Octet de la chaine recherchée
for iMark := iCountFound + 1 to SearchLen do
begin
iSearch := iSearchBufPos + iMark - iRememberFound - 1;
if iSearch >= AmtTransferred then
Break;
if (CaseSensitive and (SearchBuf[iSearch] = SearchString[iMark]))
or (not CaseSensitive and (UpCase(SearchBuf[iSearch]) = SearchString[iMark])) then
begin
Inc(iCountFound);
if iCountFound >= SearchLen then
begin
Inc(Result);
if KeepOffSet then
begin
SetLength(OffSets, Length(OffSets) + 1);
OffSets[High(OffSets)] := iReaded + iSearchBufPos - iRememberFound;
end;
iCountFound := 0;
iRememberFound := 0;
Break;
end;
end else begin
iCountFound := 0;
iRememberFound := 0;
Break;
end;
end;
Inc(iSearchBufPos, iCountFound + 1);
end;
Inc(iReaded, AmtTransferred);
end;
finally
CloseFile(FileToSearch);
end;
finally
FileMode := FileModeCopy;
end;
end; |
Partager