AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...
Thema durchsuchen
Ansicht
Themen-Optionen

aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

Ein Thema von LuckyStrike4life · begonnen am 5. Feb 2004 · letzter Beitrag vom 5. Feb 2004
Antwort Antwort
Seite 2 von 2     12   
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#11

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 13:17
Zitat von Luckie:
StringReplace dürfte bei so einer Größe tödlich sein, was die Performance angeht.
Nope, wenn ich stoxx richtig verstanden habe, sollte diese Routine pro Zeile angewendet werden, also kein Problem.

@stoxx: Ich gehe wegen der Ausrichtung der Daten (rechtsbündig) nicht von Tabs sondern Leerzeichen aus, so dass die Spalten direkt über die Zeichenposition im String indiziert werden können und eine Lösung mit Copy & Co (s.o.) als ad hoc-Lösung (ohne Hilfsklassen) am einfachsten scheint...
gruß, choose
  Mit Zitat antworten Zitat
LuckyStrike4life

Registriert seit: 22. Jul 2003
Ort: SN
105 Beiträge
 
Delphi 5 Enterprise
 
#12

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 13:17
@stoxx
leider sind es Leerzeichen, wurden nicht mit Tabulator gemacht.
Wenn du dein Code vielleicht n wenig erklären magst?

Also besser nicht mit Strings? Was würde mir denn bleiben?
- ich kann doch wirklich nichts -
  Mit Zitat antworten Zitat
LuckyStrike4life

Registriert seit: 22. Jul 2003
Ort: SN
105 Beiträge
 
Delphi 5 Enterprise
 
#13

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 13:24
Zitat von choose:
Hallo LuckyStrike4life,

generell sollte der fehlende Abschnitt in etwa so lauten:
Delphi-Quellcode:
while not Eof(tin) do
begin
  ReadLn(tin, lese);
  if DoesStringMatchCriteria(lese) then
    WriteLn(tout);
end;
Die Frage lautet also, wie ermittelst Du, ob der String das von Dir geforderte Kriterium (DoesStringMatchCriteria) erfüllt. Generell verwende ich bei der Verarbeitung von Strings gerne Hier im Forum suchenreguläre Ausdrücke in diesem Fall ist das Problem aber nicht zu letzt von der Ausführungszeit bestimmt und die Daten auch recht einfach beschaffen.
Ich empfehle Dir deshalb den Einsatz von Copy (Teilbereich extrahieren), Trim (Leerzeichen des ermittelten Teilbereichs entferen) und StrToIntDef bzw Val (Rest: Zahl als String in Zahl umwandeln) um die Daten zu verarbeiten. Ein letztlicher Vergleich gegen -300 bildet dann den Rückgabewert von DoesStringMatchCriteria.
Hm..
hab ich noch nicht mit gearbeitet...
du meinst das vermutlich in etwa so:
Delphi-Quellcode:
begin
  AssignFile(tin, 'c:\kai.txt');
  AssignFile(tout, 'c:\kaineu.txt');
  Reset(tin);
  Rewrite(tout);
  while not Eof(tin) do
  begin
     ReadLn(tin, lese);
     WriteLn(tout, Copy(lese, 31, 5) // ich lasse so von Zeichen 31 - 5 Zeichen weiter lesen
dann müsste jetzt ne Abfrage her, die schaut ob das eingelesene -300 ist, oder nicht...
- ich kann doch wirklich nichts -
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#14

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 13:34
Zitat von LuckyStrike4life:
du meinst das vermutlich in etwa so:
Delphi-Quellcode:
while not Eof(tin) do
begin
   ReadLn(tin, lese);
   WriteLn(tout, Copy(lese, 31, 5) // ich lasse so von Zeichen 31 - 5 Zeichen weiter lesen
Nein, ich meine so, wie oben beschrieben:
Delphi-Quellcode:
while not Eof(tin) do
begin
  ReadLn(tin, lese);
  if DoesStringMatchCriteria(lese) then
    WriteLn(tout);
end;
mit der Funktion DoesStringMatchCriteria, die entscheidet, ob ein String der Ausgaben angehängt werden soll, oder nicht. Nach der Beschreibung (dritte Spalte <>'-300.00') und dem gegebenen Ausschnitt (zwei führende Spaces) könnte diese Funktion so aussehen:
Delphi-Quellcode:
function DoesStringMatchCriteria(const AString: string): Boolean;
const
  ColStart = 32;
  ColWidth = 7;
begin
  Result:= Copy(AString, ColStart, ColWidth) <> '-300.00';
end;
Wenn Dich später doch der Zahlenwert oder eine andere Spalte (also auch Werte, die länger oder kürzer sind und an anderen Stellen liegen können) könntest Du die zuerst beschriebene Lösung wählen...
gruß, choose
  Mit Zitat antworten Zitat
Brüggendiek

Registriert seit: 13. Dez 2002
Ort: Dortmund
275 Beiträge
 
Delphi 5 Standard
 
#15

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 13:36
Hallo!

3 Varianten sind möglich:
1. die zu löschenden Zeilen haben alle denselben Inhalt. Dann sieht das Ganze so aus:

Delphi-Quellcode:
const loeschen = ' .00 .00 -300.00 0';

var tin, tout:Textfile;
    lese:String;
begin
  AssignFile(tin, 'c:\kai.txt'); // Name der Datei ist kai, lasse sie damit Laden
  AssignFile(tout, 'c:\kaineu.txt'); // gebe hier Name und Pfad an, wo das Resultat dann hin soll
  Reset(tin);
  Rewrite(tout);
  while not Eof(tin) do
  begin
    ReadLn(tin, lese);
    if lese <> loeschen then // Vergleich der kompletten Zeile
      writeln(tout,lese);
  end;
  CloseFile(tout);
  CloseFile(tin);
end;
Deine Beispieldaten sind ja so aufgebaut.

2. die zu löschenden Zeilen haben unterschiedlichen Inhalt, aber die Spalten sind fest definiert. Dann sieht das Ganze so aus:

Delphi-Quellcode:
const loeschen = '-300.00';
      loeschpos=32; // ggf. auszählen!
      
var tin, tout:Textfile;
    lese:String;
begin
  AssignFile(tin, 'c:\kai.txt'); // Name der Datei ist kai, lasse sie damit Laden
  AssignFile(tout, 'c:\kaineu.txt'); // gebe hier Name und Pfad an, wo das Resultat dann hin soll
  Reset(tin);
  Rewrite(tout);
  while not Eof(tin) do
  begin
    ReadLn(tin, lese);
    if Copy(lese,loeschpos,Length(loeschen)) <> loeschen then // Vergleich der betreffenden Spalten
      writeln(tout,lese);
  end;
  CloseFile(tout);
  CloseFile(tin);
end;

3. die zu löschenden Zeilen enthalten das "-300.00" an unterschiedlichen Stellen, aber dieser Wert kommt in den übrigen Zeilen garantiert nicht vor. Dann sieht das Ganze so aus:

Delphi-Quellcode:
const loeschen = '-300.00';
      
var tin, tout:Textfile;
    lese:String;
begin
  AssignFile(tin, 'c:\kai.txt'); // Name der Datei ist kai, lasse sie damit Laden
  AssignFile(tout, 'c:\kaineu.txt'); // gebe hier Name und Pfad an, wo das Resultat dann hin soll
  Reset(tin);
  Rewrite(tout);
  while not Eof(tin) do
  begin
    ReadLn(tin, lese);
    if Pos(loeschen,lese) <> 0 then // KO-Zeichenfolge suchen
      writeln(tout,lese);
  end;
  CloseFile(tout);
  CloseFile(tin);
end;
Sollte keines der Kritereien erfüllt sein, mußt Du eben die Zeile zerlegen und dann den passenden Abschnitt (hier 3. Bereich) vergleichen.


Allerdings gebe ich eines zu bedenken: Auch wenn es sehr ressourcenfressend ist, nach Windows-Norm muss die komplette Datei in den Speicher. Wozu gibt es das Pagefile - auch wenn das das System ausbremst Ich bevorzuge allerdings auch die klassische Methode mit zeilenweiser Verarbeitung.

Gruß

Dietmar Brüggendiek
Dietmar Brüggendiek
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#16

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 13:44
Hallo Dietmar,

eine gute Darstellung! Wahrscheinlich ist das Kriterium "dritte Spalte -300" tatsächlich eher so zu verstehen, wie Deine erste Variante prüft, was sehr elegant im Code aussieht ("Wenn Zeile so aussieht wie eine zu löschende")

Zitat von Brüggendiek:
nach Windows-Norm muss die komplette Datei in den Speicher.
Und wie schafft es ein DVD-Player auf einem PC mit nur 1GB RAM ein Video abzuspielen?
gruß, choose
  Mit Zitat antworten Zitat
Brüggendiek

Registriert seit: 13. Dez 2002
Ort: Dortmund
275 Beiträge
 
Delphi 5 Standard
 
#17

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 13:49
Hallo!

Zitat von choose:
Und wie schafft es ein DVD-Player auf einem PC mit nur 1GB RAM ein Video abzuspielen?
Seit wann hält sich der große Billy-Boy-Gates-jetzt-endlich an seine eigenen Standards?

Außerdem ist das ja wohl auf mehrere Dateien aufgeteilt, die nacheinander geladen werden

Gruß

Dietmar Brüggendiek
Dietmar Brüggendiek
  Mit Zitat antworten Zitat
LuckyStrike4life

Registriert seit: 22. Jul 2003
Ort: SN
105 Beiträge
 
Delphi 5 Enterprise
 
#18

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 13:49
Brüggendiek´
Danke!
Variante 1 war die richtige!!

Jetzt kommt der große Test mit der Großen Datei aufm Server .

Auch an alle anderen vielen Dank!!
- ich kann doch wirklich nichts -
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#19

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 14:45
Bei so großen Dateien würde ich es vermeiden die neuen Daten in eine Zweite zu kopieren.

Man könnte die Datei auch Binäry betrachten.

Delphi-Quellcode:
var iMove : Integer; // Gibt an um wieviel Bytes eine Zeile vorkopiert werden soll

stm := TFileStream.Create(...);

iMove := 0;
while stm.Size > stm.Position do
  begin
    sLine := ReadLine(stm);
    if MatchDel(stm) then
       begin
         Inc(iMove, Length(sLine));
         Inc(iMove, 2); // CRLF
       end
    else
       begin
         stm.Seek(soFromCurrent, -iMove);
         stm.Write(PChar(sLine)^, Length(sLine));
         stm.Write(cCRLF, 2);
         stm.Seek(soFromCurrent, iMove);
       end;
  end;
Vorsicht: Aus der kalten getippt!
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#20

Re: aus 480 MB txt Datei, bestimmte Zeilen löschen lassen...

  Alt 5. Feb 2004, 14:48
Zitat von Brüggendiek:
Hallo!

Zitat von choose:
Und wie schafft es ein DVD-Player auf einem PC mit nur 1GB RAM ein Video abzuspielen?
Seit wann hält sich der große Billy-Boy-Gates-jetzt-endlich an seine eigenen Standards?

Außerdem ist das ja wohl auf mehrere Dateien aufgeteilt, die nacheinander geladen werden

Gruß

Dietmar Brüggendiek
Es gibt auch ncoh solche Teile die nennen sich FileMappings. Darüber kann man solche Riesen-Dateien ganz einfach in den RAM-Laden.

Egal ob 10 GByte oder mehr.
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:13 Uhr.
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