Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Datei byteweise einlesen (https://www.delphipraxis.net/133868-datei-byteweise-einlesen.html)

CalganX 11. Mai 2009 09:27


Datei byteweise einlesen
 
Hallo zusammen,

da ich ziemlich aus der Übung gekommen bin, was Delphi angeht, frage ich lieber noch mal nach, bevor ich mich ins Getümmel stürze.

Ich habe eine Datei in einem proprietären Format. Die Beschreibung des Aufbaus habe ich vollständig dokumentiert vorliegen. Die Frage ist jetzt, wie ich mit Delphi eine Datei (die übrigens mit einem C-Programm zusammengestellt wurde) byteweise auslese. D.h. wenn ich jetzt in der Dokumentation stehen habe, dass dort ein 4-Byte-Wert folgt, will ich auch entsprechend auslesen.
Dass das mit readln(); geht, kann ich mich noch erinnern und das ist ja auch entsprechend in der Hilfe dokumentiert.
Gibt es noch einen anderen Weg. Und was ist der eleganteste, schönste und einfachste Weg?

Gruß
Christopher

SirThornberry 11. Mai 2009 09:31

Re: Datei byteweise einlesen
 
Ich würde dir die Verwendung von TFileStream empfehlen. Entsprechend dann die Read-Methode

Klaus01 11. Mai 2009 09:34

Re: Datei byteweise einlesen
 
.. die Dokumentation des Formats hast Du vorliegen,
warum baust Du dir dann keinen Record um die Datei datensatzsweise
zu lesen?

Grüße
Klaus

Mithrandir 11. Mai 2009 09:37

Re: Datei byteweise einlesen
 
ReadLN würde ich in diesem Falle nicht benutzen, wenn es sich nicht um ein PlainText-Format handelt. Ein falsches Zeichen, und schwupp die wuppdi ist es vorbei. ;)

Mal n Copy&Waste:

Delphi-Quellcode:
   
const
  BUF_SIZE = 1024000; //1 MB

fXMLStream := TFileStream.Create(fFilePath, fmOpenRead or fmShareDenyNone);

while not Terminated do begin
      fsBuf := StringOfChar(#00, BUF_SIZE);
      i := fXMLStream.Read(fsBuf[1], BUF_SIZE);
{Mach was mit dem Buffer }
      Finalize(fsBuf);
      if i <> BUF_SIZE then
        Terminate;
end;

CalganX 11. Mai 2009 10:32

Re: Datei byteweise einlesen
 
Hallo,

ja, prima. Ich nehme den FileStream. Damit kann ich gut arbeiten.

Danke!
Christopher

Meflin 11. Mai 2009 10:33

Re: Datei byteweise einlesen
 
Zitat:

Zitat von Klaus01
warum baust Du dir dann keinen Record um die Datei datensatzsweise
zu lesen?

Und wie ginge das :gruebel:

Mithrandir 11. Mai 2009 10:37

Re: Datei byteweise einlesen
 
Vermutlich mit typisierten Dateien und allem drumherum. Man muss halt nur schauen, dass man Typen findet, die zur Definition passen. ;)

mr_emre_d 11. Mai 2009 10:44

Re: Datei byteweise einlesen
 
Delphi-Quellcode:
var
  F: File of Byte;
  X: Array of Byte;
begin
  AssignFile( F, '<Path>' );
  // Falls Datei existiert, dann öffnen und FilePointer reseten
  Reset( F );
  // und wenn nicht, dann erstellen + öffnen usw ..
  Rewrite( F );
 
  SetLength( X, FileSize( F ) );
  // lesen:
  BlockRead( F, X[0], Length(X) );
  // schreiben
  BlockWrite( F, X[0], Length(X) );

  // Filepointer setzen:
  Seek( F, 0 );

  // Anschließend schließen - falls etwas geändert wurde, wirds gespeichert
  CloseFile( F );
end;

SirThornberry 11. Mai 2009 16:45

Re: Datei byteweise einlesen
 
man kann auch mit TFileStream Records einlesen. Anstelle eines Stringbuffers eben einfach eine Recordvariable verwenden.

stoxx 12. Mai 2009 12:03

Re: Datei byteweise einlesen
 
wenn die gelesene blockgröße gleich der zu lesenden Recordgröße ist, sind die beschriebenen Methoden sehr, sehr langsam. Um viele Faktoren.
Der zu verwendente Lesepuffer sollte bei heutigen Festplatten schon sehr groß sein, 64 kb ist eine angenehme Größe.
Deshalb sollte man also mit einer großen Buffersize lesen und dann müsste man noch umständlich diesen Großen Block auf mehrere Deiner Records aufteilen. Bei diesem Verfahren sollte dann zusätzlich noch die zu lesende Buffersize ein Vielfaches der zu lesenden RecordSize sein, damit es keine Überschneidungen an den Blockgrenzen geben kann, in diesem Falle wird es dann nämlich noch komplizierter.

Das alles kann man sehr einfach haben und sich das nachdenken sparen, wenn man eine Kombination aus TFilestream und TReader verwendet. TReader kann das alles schon selbst.

also quasi sowas:

Delphi-Quellcode:
const
  BufferSize = $10000; // 65536;  64 kb


function LoadFromFile(const aFileName : String) :Integer;
var
  f : TFileStream;
  r : TReader;
  i : Integer;
  myRecord : TMyRecord;
  recSize : Integer;
begin
  Result:=0;
  recSize := SizeOf(TMyRecord);
  f:=TFileStream.Create( aFilename , fmOpenRead or fmShareDenyWrite);
  try
    r:=TReader.Create(f ,BufferSize);
    try

      for i:=0 to (f.Size Div recSize) -1 do
        r.Read(myRecord , recSize );

        ... // myRecord verarbeiten

        Inc(Result);
      end;
    finally
      r.Free;
    end;
  finally
    f.Free;
  end;
end;
siehe hier nochmal auch: http://delphi.pjh2.de/articles/files/files.php


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:13 Uhr.
Seite 1 von 2  1 2      

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