Delphi-PRAXiS
Seite 2 von 4     12 34      

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)

Der_Unwissende 17. Jan 2007 12:49

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von capo
Delphi-Quellcode:
  while not(eof(fd1)) do
    begin
      readln(fd1,S);
      if (trim(S)<>'') and (S <> LAST) then
        writeln(fd2,S);
      Last := S;
    end;

Hier solltest Du schonmal unterscheiden, ob S leer war oder nicht (sonst suchst Du auch nur nach einer Leerzeile nur noch nach einer weiteren Leerzeile).

Delphi-Quellcode:
  while not(eof(fd1)) do
    begin
      readln(fd1,S);
      if (trim(S)<>'') and (S <> LAST) then
      begin
        writeln(fd2,S);
        Last := S;
      end;
    end;
So, damit hast Du dann die Variante, die alle aufeinander folgenden, gleichen Zeilen löscht.

Möchtest Du allgemeiner jede Zeile nur einmal haben, dann versuche es lieber mit:
Delphi-Quellcode:
var listAlt, listNeu: TStringList;
    i: Integer;
begin
  listAlt := TStringList.Create;
  // laden wie gehabt
  listAlt.LoadFromFile('...');
 
  listNeu := THashedStringList.Create;
  for i := 0 to listAlt.Count - 1 do
  begin
    if listNeu.indexOf(listAlt[i]) < 0 then
    begin
      listNeu.add(listAlt[i]);
    end;
  end;

  listNeu.SaveToFile('...');
end;
Wie Du hier siehst, wird der Hash nur für die neue Liste verwendet, die alte sollte möglichst keinen haben, da Du hier eh alle Zeilen betrachten wirst. Das Berechnen eines Hashs bringt dir also keinen Vorteil, kostet aber Zeit. Wird nun nach dem Index eines Strings gesucht, so kann dies mit einem Hash sehr viel schneller durchgeführt werden als ohne, für die neue Liste lohnt sich also dieser Hash. Alternativ gibt es noch mind. zwei Möglichkeiten, Du kannst die HashedStringList auch durch eine Map (Alzaimar hat mal eine für Strings als Schlüssel zur Verfügung gestellt) ersetzen (die ist vielleicht noch schneller). Oder aber du setzt bei der neuen StringList die Eigenschaft sorted auf True und die Eigenschaft Duplicates auf dupIgnore. Was davon die höchste Perfomance erzielt kann ich so nicht sagen, musst Du einfach mal testen.

Gruß Der Unwissende

Mavarik 17. Jan 2007 13:11

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von Der_Unwissende
Delphi-Quellcode:
  while not(eof(fd1)) do
    begin
      readln(fd1,S);
      if (trim(S)<>'') and (S <> LAST) then
      begin
        writeln(fd2,S);
        Last := S;
      end;
    end;

Ja genau, das Begin end hat gefehlt...

Wer will schon aus einen Logfile alle doppelten killen? Oder ist das so..

Frank

Mavarik 17. Jan 2007 13:14

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von capo
Hallo
so mach ich das nun aber es sind immer noch doppelte Einträge vorhanden.
gruss capo

Die werden dann nicht 100%ig gleich sein...

ggf. mal

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  fd1,fd2 : Textfile;
  S,Last : string;
begin
  assignfile(fd1,'C:\logfile.txt');
  assignfile(fd2,'C:\logfile.neu');
  reset(fd1);
  rewrite(fd2);
  Last := '';
  while not(eof(fd1)) do
    begin
      readln(fd1,S);
      if (trim(S)<>'') and (uppercase(S) <> LAST) then
        begin
          writeln(fd2,S);
          Last := uppercase(S);
        end;
    end;

  Closefile(fd2);
  Closefile(fd1);
  delete(fd1);
  rename(fd1,'C:\logfile.txt');
end;
Frank

Der_Unwissende 17. Jan 2007 13:23

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von Mavarik
Wer will schon aus einen Logfile alle doppelten killen? Oder ist das so..

Hm, wo steht denn das es um ein Log-File geht? Also mir kommt es so vor, als ob die Fragen um was für eine Datei es sich handelt (irgendwo am Anfang wurde nach dem Format der Zeilen) und ob jetzt wirklich alle doppelten oder nur aufeinander folgende Doppelte entfernt werden sollen nicht weiter eingegangen wurde.

Aber selbst im Log-File, wenn Du nur sehen möchtest, was für Probleme aufgetreten sind... Also es gibt bestimmt Dateien, wo man sich einfach mal die disjunkten Zerlegungen anschauen möchte. Aber mal die Frage andersrum, welches Logfile speichert denn mehrfach aufeinander folgend exact die gleiche Zeile? (schon wenn Datum und Uhrzeit im Log vorkommen hat man hier ja schnell zwei unterschiedliche Strings).

Mavarik 17. Jan 2007 13:29

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Na ich würde sagen:
Delphi-Quellcode:
if FileExists('logfile.txt') then
Sieht mir sehr nach einem Logfile aus...

Frank

Der_Unwissende 17. Jan 2007 13:40

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Zitat:

Zitat von Mavarik
Na ich würde sagen:
Delphi-Quellcode:
if FileExists('logfile.txt') then
Sieht mir sehr nach einem Logfile aus...

Das ist doch reine Spekulation! :mrgreen:

Ok, ich fang an und lerne Lesen! Ihr habt's ja so gewollt!

capo 17. Jan 2007 17:00

Re: 80 MB Datei - doppelte Zeilen entfernen
 
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

capo 17. Jan 2007 18:42

Re: 80 MB Datei - doppelte Zeilen entfernen
 
Delphi-Quellcode:
var listAlt, listNeu: TStringList;
    i: Integer;
begin
  listAlt := TStringList.Create;
  // laden wie gehabt
  listAlt.LoadFromFile('...');

  listNeu := THashedStringList.Create;
  for i := 0 to listAlt.Count - 1 do
  begin
    if listNeu.indexOf(listAlt[i]) < 0 then
    begin
      listNeu.add(listAlt[i]);
    end;
  end;

  listNeu.SaveToFile('...');
end;
damit läuft es nun schon eine stunde, nichts passiert

Christian Seehase 17. Jan 2007 18:52

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

bist Du sicher, dass das Programm überhaupt schon mit dem Einlesen der Datei fertig ist?
80MB in eine Stringlist einzulesen kann ziemlich dauern.

Wenn Du wirklich nur doppelte Zeilen finden willst, halte ich es für sinnvoller die Datei zeilenweise zu lesen (ReadLn usw.), jeweils einen MD5-Hash über der Zeile zu bilden, diesen in einer STringList suchen. Ist er nicht vorhanden, die Zeile in eine Zieldatei wegschreiben, und den Hashwert mit in die Tabelle aufnehmen.

Die Eigenschaft Capacity (Anzahl zu erwartender Zeilen) einer StringList solltest Du bei solchen Aktionen auf einen möglichst korrekten Wert einstellen, um Geschwindigkeit herauszuholen.

MrKnogge 17. Jan 2007 19:00

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

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

Gruß


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:37 Uhr.
Seite 2 von 4     12 34      

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