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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| {* -----------------------------------------------------------------------------
la Fonction SearchStringInBigFileLazy Permet de Chercher une Chaine dans Fichier de plus de 2Go, la fonction renvoi le nombre d'occurence
@param FileName Chaine contenant le nom du Fichier
@param SearchString Chaine à chercher dans le fichier
@param Threshold Si le nombre de chaine trouvé atteind ce nombre, la Recherche s'arrête
@param CaseSensitive Boolean True A est différent de a, False, ignore la casse (plus lent)
@param AcceptOverlap Boolean True si le mot à chercher est une répétition cela compte les occurences qui se chevauche, False chaque lettre d'une occurence ne peut être comptabilisé qu'une seule fois (exemple on chercher coco, le fichier contient cocococo, True = 3, False = 2)
@return Nombre d'occurence Trouvé
------------------------------------------------------------------------------ }
function SearchStringInBigFileLazy(const FileName, SearchString: string; Threshold: Integer = MaxInt; CaseSensitive: Boolean = True; AcceptOverlap: Boolean = False): 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;
LastFound: Boolean;
UpSearchString: string;
begin
SearchLen := Length(SearchString);
Result := 0;
if SearchLen <= 0 then
Exit;
if not CaseSensitive then
UpSearchString := UpperCase(SearchString);
SetLength(SearchBuf, BUF_SIZE);
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;
LastFound := False;
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]) = UpSearchString[iMark])) then
begin
Inc(iCountFound);
LastFound := iCountFound >= SearchLen;
if LastFound then
begin
Inc(Result);
if iCountFound = Threshold then
Exit;
iCountFound := 0;
iRememberFound := 0;
Break;
end;
end else begin
iCountFound := 0;
iRememberFound := 0;
Break;
end;
end;
if iSearch >= AmtTransferred then
Break;
if LastFound then
begin
LastFound := False;
if AcceptOverlap then
Inc(iSearchBufPos, 1)
else
Inc(iSearchBufPos, SearchLen)
end
else
Inc(iSearchBufPos, 1);
end;
Inc(iReaded, AmtTransferred);
end;
finally
FileClose(FileToSearch);
end;
end; |
Partager