Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Textdatei bei 100 MB Truncaten (https://www.delphipraxis.net/185894-textdatei-bei-100-mb-truncaten.html)

af99 16. Jul 2015 09:18

Delphi-Version: XE5

Textdatei bei 100 MB Truncaten
 
Hallo Zusammen,

ich möchte eine Textdatei auf 100MB kürzen.
Folgendes habe ich gemacht
Delphi-Quellcode:
var
  FileStream : TFileStream;

begin
  FileStream := TFileStream.Create(ExtractFilePath(Application.ExeName) + 'log.txt', fmopenreadwrite);
  try
    if FileStream.Size > 1000000 then
    begin
      FileStream.Size := 1000000;
      FileStream.Position := FileStream.Size;
    end;
  finally
    FileStream.Free;
  end;
end;
Jetzt ist es in der Regel so das die letzet Zeile irgendwo abgeschnitten wird. Ich möchte aber das in der Datei nur vollständige Zeilen enthalten sind. Wie kann ich also die letzte unvollständige Zeile löschen?

Viele Grüße
Andreas

Klaus01 16. Jul 2015 09:27

AW: Textdatei bei 100 MB Truncaten
 
Hallo,

Du könntest beim Beschreiben der LogDatei prüfen ob die maximale Dateigröße erreicht ist.
Ist sie erreicht wird die Datei abgeschnitten - bevor ein neuer Eintrag eingetragen wird.

Grüße
Klaus

BUG 16. Jul 2015 09:43

AW: Textdatei bei 100 MB Truncaten
 
Bevor du die Größe änderst, lade einen Block vor der Stelle wo du kürzen willst. Dann suche rückwärts bis zum ersten Zeilenumbruch. Wenn du da keinen findest, musst du eben noch einen Block vorher laden.

Dann hast du die Stelle und kannst die Größe entsprechend ändern.

af99 16. Jul 2015 11:53

AW: Textdatei bei 100 MB Truncaten
 
@Klaus01: geht nicht da ich immer die alten Einträge abschneiden möchte.
@BUG: wie finde ich denn die Stelle bei genau 100MB?

BUG 16. Jul 2015 12:04

AW: Textdatei bei 100 MB Truncaten
 
Zitat:

Zitat von af99 (Beitrag 1308864)
@BUG: wie finde ich denn die Stelle bei genau 100MB?

So:
Delphi-Quellcode:
FileStream.Position := 1000000;
. Du möchtest allerdings ein Stück nach vorne, um von da aus bis 1MB zu lesen.

af99 16. Jul 2015 14:49

AW: Textdatei bei 100 MB Truncaten
 
ok, soweit bin ich nun
Delphi-Quellcode:
const
  MaxLen = 1024;
var
  FileStream : TFileStream;
  Writer: TStreamWriter;
  Reader: TStreamReader;
  buffer: string;
  posCRLF: Integer;

begin
  try
    FileStream := TFileStream.Create(ExtractFilePath(Application.ExeName) + 'log.txt', fmopenRead);//fmOpenRead or fmShareDenyWrite);
    Writer := TStreamWriter.Create(FileStream);
    Reader := TStreamReader.Create(FileStream);

    filestream.Position := 999900;

    buffer := Reader.ReadToEnd;

    posCRLF := pos('#13#10' , buffer);

    ShowMessage('pos: ' + inttostr(posCRLF));

    ShowMessage('buffer: ' + buffer);

    if FileStream.Size > 1000000 then
    begin
      FileStream.Size := 1000000;
    end;
  finally
    Writer.Free;
    Reader.Free;
    FileStream.Free;
  end;
end;
Mein pos mit dem ich dachte das ich das carriage return finden kann findet es aber nicht :-(
Wie kann ich denn das carriage return finden?

Gruss
Andreas

Klaus01 16. Jul 2015 14:52

AW: Textdatei bei 100 MB Truncaten
 
Hallo,

das CRLF wird in der Datei nicht als String '#13#10' enthalten sein.
Die entsprechenden Zeichen musst Du suchen char(13).

Grüße
Klaus

Mavarik 16. Jul 2015 15:49

AW: Textdatei bei 100 MB Truncaten
 
Delphi-Quellcode:
posCRLF := pos(#13#10 , buffer);
Unter der Voraussetzung, dass in der Textdatei überhaupt #13#10 steht und nicht nur #13 oder nur #10 oder ganz komisch #10#13

Capstone 16. Jul 2015 21:15

AW: Textdatei bei 100 MB Truncaten
 
photoshop_CC_x64.rar.txt hat übrigens ~2600 MB ...

mußte also 26 x die Text-Datei kürzen :D

** hust **

af99 17. Jul 2015 08:12

AW: Textdatei bei 100 MB Truncaten
 
Irgendwie bekomme ich es nicht hin genau bis zum CR LF abzuschneiden. So habe ich es versucht
Delphi-Quellcode:
var
  FileStream : TFileStream;
  Reader: TStreamReader;
  buffer: string;
  posCRLF: Integer;

begin
  try
    FileStream := TFileStream.Create(ExtractFilePath(Application.ExeName) + 'log.txt', fmopenreadwrite);
    Reader := TStreamReader.Create(FileStream);

    if FileStream.Size > 1000000 then
      FileStream.Size := 1000000;
    filestream.Position := 999900;
    buffer := Reader.ReadToEnd;

    FileStream.Size := 999900 + SizeOf(copy(buffer, 1, pos(char(13) , buffer)));
  finally
    Reader.Free;
    FileStream.Free;
  end;
end;
Er schneidet aber immer zu viel ab.
Weis einer wie ich ich es richtig berechnen muss?

Gruss
Andreas

af99 17. Jul 2015 09:57

AW: Textdatei bei 100 MB Truncaten
 
ich hab nochmal nachgeschaut

FileStream.Size gibt die Größe in Bytes an
SizeOf() gibt auch die Größe in Bytes an

Wenn ich also das mache
FileStream.Size := 999900 + SizeOf(copy(buffer, 1, pos(char(13) , buffer)))
dann sollte ich doch am Ende der Zeile landen.

Ist aber leider nicht so?!

p80286 17. Jul 2015 10:12

AW: Textdatei bei 100 MB Truncaten
 
mit
Delphi-Quellcode:
pos
findest Du immer das erste Auftreten eines Strings/Zeichen. Du willst aber das letzte.
wie wäre es mit so etwas z.B.

Delphi-Quellcode:
i:=length(buffer);
repeat
  dec(i,1);
until (i<0) or buffer[i]=$0D;
if buffer[i]=$0D then.......
Gruß
K-H

P.S.
Mit anderen worten stand das schon in #3

Der schöne Günther 17. Jul 2015 10:38

AW: Textdatei bei 100 MB Truncaten
 
Euch ist aber auch klar dass man vorne auch nur einfach so abschneiden kann wenn die Datei kein Byte Order Mark hat, oder?

Das würde ich mir wenigstens am Anfang noch auslesen, dann ausrechnen, wie viel wir wegwerfen wollen, im Stream soweit (minus die Größe des BOM) vorwärts wandern, BOM wieder schreiben und zumachen.

af99 17. Jul 2015 11:00

AW: Textdatei bei 100 MB Truncaten
 
hmmm, ja ok. Damit bekomme ich die Position der CRLF. Ich denke die hatte ich vorher auch schon. Wie bekomme ich aber nun die Länge in Bytes des Buffers von Anfang bis zu CRLF?

p80286 17. Jul 2015 11:59

AW: Textdatei bei 100 MB Truncaten
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1309005)
Euch ist aber auch klar dass man vorne auch nur einfach so abschneiden kann wenn die Datei kein Byte Order Mark hat, oder?

Das würde ich mir wenigstens am Anfang noch auslesen, dann ausrechnen, wie viel wir wegwerfen wollen, im Stream soweit (minus die Größe des BOM) vorwärts wandern, BOM wieder schreiben und zumachen.

Hab ich da was verpasst? Warum willst Du vorne was abschneiden?
So wie ich es verstanden habe soll eine Textdatei (Zeilenende=#13#10) nach 100 MB (oder 99,5674593 MB) abgeschnitten werden.

Dafür würde ich mehrere Buffer zu je xxByte lesen und schreiben und im letzten vor Erreichen der 100MB Grenze suche ich das letzte #13#10 (oder wie auch immer das Zeilenende aussieht) und schreibe den Bufferinhalt bis zu dieser Position weg.
(hoffentlich ist der Buffer so groß, daß auch die längsten Zeilen da hinein passen!)

Da ist mir doch vollkommen egal was für eine Kodierung/Zeichensatz die Datei hat. Konkret muß ich nur die Kodierung von "Zeilenende" kennen.

Gruß
K-H

Der schöne Günther 17. Jul 2015 12:03

AW: Textdatei bei 100 MB Truncaten
 
[QUOTE=p80286;1309014]So wie ich es verstanden habe soll eine Textdatei (Zeilenende=#13#10) nach 100 MB (oder 99,5674593 MB) abgeschnitten werden.[/URL]

Ok, dann halt so. Da ich "log.txt"-Datei gelesen hatte dachte ich man schneidet dort ältere Nachrichten ab statt neuere.

af99 17. Jul 2015 12:38

AW: Textdatei bei 100 MB Truncaten
 
ups, da hast Du vollkommen Recht. Ich muss also oben abschneiden.

p80286 17. Jul 2015 12:40

AW: Textdatei bei 100 MB Truncaten
 
@Schönster aller Günther
Hast Du eine neue Kristalkugel oder kannst Du Gedanken lesen?:stupid:

Gruß
K-H

Klaus01 17. Jul 2015 12:46

AW: Textdatei bei 100 MB Truncaten
 
.. wenn neue log Einträge via add hinzugefügt werdem werden diese am Ende der Datei angehängt und die lätesten Enträge sind am Anfang der Datei.

Werden neue log Einträge via insert immer am Anfang der Datei eingefügt sind die ältesten Einträge am Ender der Datei.

Grüße
Klaus

Mavarik 18. Jul 2015 17:51

AW: Textdatei bei 100 MB Truncaten
 
Zitat:

Zitat von Klaus01 (Beitrag 1309027)
Werden neue log Einträge via insert immer am Anfang der Datei eingefügt sind die ältesten Einträge am Ender der Datei.

Wie machst Du den einen Insert auf eine Datei?

Auf die schnelle ungetestet:

100.000 Bytes Truncate

Delphi-Quellcode:
procedure Truncate100;
var
  FS : TFileStream;
  Buffer : TDynByteArray;
  I     : Integer;
begin
  FS := TFileStream.Create('log.txt',fmOpenread);
  try
    if FS.Size > 100000 then
      begin
        FS.Seek(100000,soEnd);
        Setlength(Buffer,100000);
        FS.ReadBuffer(Buffer[0],100000);
        FS.Free;
        i := 0;
        While i < 99999 do
          begin
            if (Buffer[i] = 13) and Buffer[i+1] = 10 then
              begin
                inc(I,2);
                break;
              end;

            inc(i);
          end;

        FS := TFileStream.Create('log.txt',fmOpenWrite);
        try
          FS.WriteBuffer(Buffer[i],100000-i);
        finally
          FS.Free;
        end;
      end;
  finally
    FS.Free;
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:38 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