Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi 80 MB Datei - doppelte Zeilen entfernen (https://www.delphipraxis.net/84459-80-mb-datei-doppelte-zeilen-entfernen.html)

Nils_13 17. Jan 2007 19:30

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von MrKnogge
Moin Christian,

wäre es nicht schneller, die Strings direkt zu vergleichen, statt erst den "Umweg" per MD5 zu gehen ?

Gruß

Ich bin zwar nicht Christian, aber soweit ich weiß ist direkt vergleichen schneller.

capo 17. Jan 2007 19:33

Re: 80 MB Datei - doppelte Zeilen entfernen
 
hallo und danke für eure antworten.
habs nun so gelöst:
dauert damit ca. 10 minuten
merkwürdigerweise werden dabei auch einige ; in der datei gelöscht.
insofern ist diese lösung doch nicht so geeignet.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  SL: TStringList;
  I: integer;
begin
  SL := TStringList.Create;
  try
    SL.BeginUpdate;
    try
      SL.LoadFromFile('C:\file.txt');
      SL.Sort;
      for i := SL.Count - 2 downto 0 do
        if SL[i] = SL[i + 1] then
          SL.Delete(i + 1);
      SL.SaveToFile('C:\file_ok.txt');
    finally
      SL.EndUpdate;
    end;
  finally
    SL.Free;
  end;
  Showmessage('Fertig...');
end;
hallo Christian
hast du evt. ein beispiel, ein paar zeilen?


gruss capo

Christian Seehase 17. Jan 2007 21:10

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Moin capo,

so würde ich das wohl bei einer solchen Dateigrösse machen:

Delphi-Quellcode:
var
  fIN  : TextFile;
  fOUT : TextFile;
  sl   : TStringList;
  sLine : string;
  sMD5  : string;

begin
  sl := TStringList.Create;
  try
    sl.Sorted := true;
    AssignFile(fIN,'<Pfad der Quelldatei>');
    AssignFile(fOUT,'<Pfad der Zieldatei>');
    Reset(fIN);
    Rewrite(fOUT);
    try
      Readln(fIn,sLine);
      while not Eof(fIN) do begin
        sMD5 := MD5Print(MD5String(sLine));
        if sl.IndexOf(sMD5) = -1 then begin
          sl.Add(sMD5);
          Writeln(fOUT);
        end;
        Readln(fIN,sLine);
      end;
    finally
      CloseFile(fOUT);
      CloseFile(fIN);
    end;
  finally
    FreeAndNil(sl);
  end;
end;
für die MD5-Funktionen kannst Du dies nehmen.

Sicher kostest es Zeit die MD5 zu berechnen, um einen doppelten String zu ermitteln, aber bei der Datenmenge könnte es schneller sein. Eine andere Variante:

Delphi-Quellcode:
var
  fIN  : TextFile;
  slOut : TStringList;
  sLine : string;

begin
  slOut := TStringList.Create;
  try
    slOut.Capacity     := 1000000;
    slOut.Sorted       := True;
    slOut.CaseSensitive := False;
    slOut.Duplicates   := dupIgnore;
    AssignFile(fIN,'<Pfad der Quelldatei>');
    Reset(fIN);
    try
      Readln(fIn,sLine);
      while not Eof(fIN) do begin
        slOut.Add(sLine);
        Readln(fIN,sLine);
      end;
    finally
      CloseFile(fIN);
    end;
    slOut.SaveToFile('<Pfad der Zieldatei>');
  finally
    FreeAndNil(slOut);
  end;
end;

capo 17. Jan 2007 21:18

Re: 80 MB Datei - doppelte Zeilen entfernen
 
hallo christian
dankeschön für deine beispiele.
:-D

Hawkeye219 17. Jan 2007 22:21

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Moin Christian,

du ignorierst in beiden Varianten die letzte Zeile der Eingabedatei. Das Ergebnis der ersten Variante ist sicher auch nicht das gewünschte.

Korrektur der Variante 1:
Delphi-Quellcode:
[...]
try
//  Readln(fIn,sLine); // entfernt
  while not Eof(fIN) do begin
    Readln(fIn,sLine); // neu
    sMD5 := MD5Print(MD5String(sLine));
    if sl.IndexOf(sMD5) = -1 then begin
      sl.Add(sMD5);
      Writeln(fOUT, sLine); // korrigiert
    end;
//    Readln(fIN,sLine); // entfernt
  end;
finally
[...]
Korrektur der Variante 2:
Delphi-Quellcode:
[...]
try
//  Readln(fIn,sLine); // entfernt
  while not Eof(fIN) do begin
    Readln(fIn,sLine); // neu
    slOut.Add(sLine);
//    Readln(fIN,sLine); // entfernt
  end;
finally
[...]
Gruß Hawkeye

Mavarik 18. Jan 2007 07:29

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von capo
Logfile.txt heisst die Datei nur weil ich den Code aus einem anderen Programm von mir übernommen habe.
Es sind Adressen um die es geht.
gruss capo

Oh mann :stupid:

Du läßt uns hier rumrätzeln, weil Du Deine Frage so schwammig gestellt hast...

Na was den nu?

Sind die doppelten jetzt über die Datei verteilt oder liegen die hintereinander?

Wenn es 80MB sind und es sich dabei um Adressen handelt sind das bei typischer Adressgröße ca. 500.000-700.000 Adressen...(Zeilen), richtig?

Dann vielleicht sowas...

Delphi-Quellcode:
type
   TSorter = Record
              CRC  : longint;
              Zeile : longint;
            end;
var
   Sort : array of TSorter;
   Count : integer;
   S    : String;
   i    : integer;
begin
  assignfile(fd1,'Adressen.txt');
  reset(fd1);
  Count := 0;
  Setlength(Sort,500000);
  while not(eof(fd1)) do
    begin
      readln(fd1,S);
      if length(Sort) > Count+1 
        then begin
               Sort.CRC  := CRC4(S); // Oder auch den HD5
               Sort.Zeile := Count;
     
             end
        else begin
               Setlength(Sort,Count + 10000); // Je größer die Zahl, desto schneller...
             end;

      inc(Count)
    end;
  Closefile(fd1);

  QSort(Sort,0,Count); // Gibt es von mir hier eine Kombo...

  // Den rest überlasse ich Dir...
  // Doppelte aus dem Array löschen...
  // Dann nur die Zeilen in die andere Dateikopieren, wenn Count in sort.Zeile
   
end;
Frank :coder:

PS.: Und wenn es dann noch nicht schnell genug ist... Zip die Adress-Datei zusammen und leg sie irgendwo hin...
Denn das Antworten hier dauert jetzt schon länger als eine Konvertierung.. :-)

smudo 18. Jan 2007 07:57

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Ich weiß jetzt nicht, was Franks QSort so macht, aber wenn die Reihenfolge der Elemente in der Liste geändert werden darf, würde ich auf jeden Fall Shellsort vorschlagen. Das sollte bei der Datenmenge das schnellste Verfahren sein.

Baue doch einfach mal ein paar Cardinals ein und ermittle den TickCount. Dann weißt du, an welcher Stelle du am Besten optimieren solltest.

Edit: Noch was. Was machst du denn mit den Adressen? Falls du vorhast, sie anschließend in eine DB einzulesen, dann spar dir doch das Bearbeiten der Datei und mach die Logik lieber mit der DB.

Mavarik 18. Jan 2007 08:23

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von smudo
Ich weiß jetzt nicht, was Franks QSort so macht

Ist ein objektorientierte Quicksort Komponente ist i.d.R. die schnelleste Möglichkeit... (Bitte keine Diskussion hierrüber anfangen ) :lol:


Zitat:

Zitat von smudo
Edit: Noch was. Was machst du denn mit den Adressen? Falls du vorhast, sie anschließend in eine DB einzulesen, dann spar dir doch das Bearbeiten der Datei und mach die Logik lieber mit der DB.

Genau, das wäre mein nächster Vorschlag gewesen...

Frank :coder:

capo 18. Jan 2007 08:45

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Hallo und auch gleich ein SORRY.
Ja es sind Adressen.
Ich dachte es ist egal was in den Zeilen steht wenn ich sage das diese doppelt oder mehrfach vorkommen.
Wieder etwas gelernt.
Danke an ALLE
Gruss Capo

Mavarik 18. Jan 2007 08:54

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von capo
Hallo und auch gleich ein SORRY.
Gruss Capo

Ja sind Deine Fragen damit beantwortet?

Frank


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz