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 77 78 79 80 81 82
| {* -----------------------------------------------------------------------------
la Fonction SearchStringInBigFile Permet de Chercher une Chaine dans Fichier de plus de 2Go, la fonction renvoi le nombre d'occurence, et peu renvoyer un tableau contenant le premier octet de chaque occurence dans le fichier
@param FileName Chaine contenant le nom du Fichier
@param SearchString Chaine à chercher dans le fichier
@param OffSets Tableau d'Entier qui contiendra les positions de occurences trouvés
@param KeepOffSet Boolean True rempli OffSets, False, ne rempli pas OffSets
@param Threshold Si le nombre de chaine trouvé atteind ce nombre, la Recherche s'arrête
@return Nombre d'occurence Trouvé
------------------------------------------------------------------------------ }
function SearchStringInBigFile(const FileName, SearchString: string; out OffSets: TIntegerDynArray; KeepOffSet: Boolean = False; Threshold: Integer = MaxInt): Integer;
const
BUF_SIZE: Integer = 1024;
var
FileToSearch: Integer;
FileLength: Int64;
SearchBuf: array of Char;
iSearchBufPos, iSearch, iMark, iCountFound, iRememberFound, iReaded: Integer;
SearchLen: Integer;
AmtTransferred: Integer;
begin
SetLength(SearchBuf, BUF_SIZE);
SearchLen := Length(SearchString);
Result := 0;
iReaded := 0;
FileToSearch := FileOpen(FileName, fmOpenRead);
if FileToSearch < 0 then
Exit;
try
FileLength := FileSeek(FileToSearch, 0, FILE_END);
FileSeek(FileToSearch, 0, FILE_BEGIN);
iCountFound := 0;
while iReaded < FileLength do
begin
AmtTransferred := FileRead(FileToSearch, SearchBuf[0], BUF_SIZE); // [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 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;
end;
if iCountFound = Threshold then
Exit;
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
FileClose(FileToSearch);
end;
end; |
Partager