cs_Shai
Messages postés
50
Date d'inscription
mardi 8 octobre 2002
Statut
Membre
Dernière intervention
21 décembre 2011
24 janv. 2008 à 16:24
Si le fichier fait plusieurs Mo, avec une TStringList, tu charge alors plusieurs Mo en mémoire, voici une fonction qui recherche dans un fichier une chaine, et renvoie sa position, j'ai la même fonction pour les fichiers de plus de 2Go ...
{* -----------------------------------------------------------------------------
la Fonction SearchStringInFile Permet de Chercher une Chaine dans Fichier, 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 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 SearchStringInFile(const FileName: string; SearchString: string; out OffSets: TIntegerDynArray; KeepOffSet: Boolean False; CaseSensitive: Boolean True; AcceptOverlap: Boolean = False): 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;
LastFound: Boolean;
begin
SearchLen := Length(SearchString);
Result := 0;
if SearchLen <= 0 then
Exit;
SetLength(SearchBuf, BUF_SIZE);
iReaded := 0;
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;
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]) = SearchString[iMark])) then
begin
Inc(iCountFound);
LastFound := iCountFound >= SearchLen;
if LastFound 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;
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
CloseFile(FileToSearch);
end;
finally
FileMode := FileModeCopy;
end;
end;
Shai Le Troll
!! Aide via F1 !! Pensez-y !!
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer