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
| // Lecture d'une chaîne délimitée par un retour chariot
// à la position courante d'un flux.
function ReadStringFromStream(var S:TFileStream;Offset:Int64):string;
var k:Char;
begin
Result := '';
S.Position := Offset;
S.Read(k,SizeOf(k));
while (S.Position < S.Size) and not(k in [#10,#13]) do
begin
Result := Result + k;
S.Read(k,SizeOf(k));
end;
if (S.Position < S.Size) and (k = #13) then
begin
S.Read(k,SizeOf(k));
if k <> #10 then S.Position := S.Position - 1;
end;
end;
procedure JumpToNextStringInStream(var S:TFileStream);
var k:Char;
begin
S.Read(k,SizeOf(k));
while (S.Position < S.Size) and not(k in [#10,#13]) do S.Read(k,SizeOf(k));
if (S.Position < S.Size) and (k = #13) then
begin
S.Read(k,SizeOf(k));
if k <> #10 then S.Position := S.Position - 1;
end;
end;
procedure Doublons(FileName:string;Str:TStrings;Lab:TLabel;PB:TProgressBar); // ComCtrls
var S : TFileStream;
Offsets : Array of Int64;
L,I,J : Integer;
Line : String;
C,M : Int64;
begin
S := nil;
try
try
S := TFileStream.Create(FileName,fmOpenRead);
if Assigned(PB) then PB.Max := 100; // TProgressBar
if Assigned(Str) then Str.Clear;
// Création liste des offsets de lignes
if Assigned(Lab) then
begin
Lab.Caption := Format('Création de la liste des offsets - taille du fichier : %d octets',[S.Size]);
Lab.Update;
end;
while S.Position < S.Size do
begin
if Assigned(PB) then PB.Position := 100 * S.Position div S.Size;
L := Length(Offsets);
SetLength(Offsets,L + 1);
Offsets[L] := S.Position;
JumpToNextStringInStream(S);
end;
L := Length(Offsets);
L := 1000;
C := 0;
M := L * (L - 1) div 2;
if M <= 0 then M := 1;
if Assigned(Str) then Str.BeginUpdate;
if Assigned(PB) then PB.Position := 0;
for I := 0 to L - 2 do
begin
Line := ReadStringFromStream(S,Offsets[I]);
if Assigned(Lab) then
begin
Lab.Caption := Format('Recherche des doublons - ligne %d / %d',[I+2,L]);
Lab.Update;
end;
for J := I + 1 to L - 1 do
begin
inc(C);
if Line = ReadStringFromStream(S,Offsets[J])
then begin
// Hiii, un doublon !
// Ici, on peut faire ce qu'on veut, stocker le doublon
// contenu dans Line dans un TStringList par exemple.
if Assigned(Str) then Str.Add(Format('Lignes %d et %d (%s)',[I,J,Line]));
if Assigned(PB) then PB.Position := 100 * C div M;
end
end
end;
if Assigned(Str) then Str.EndUpdate;
except
On E:Exception do ShowMessage(E.Message);
end;
finally
if S <> nil then FreeAndNil(S);
Finalize(Offsets);
end;
end; |
Partager