![]() |
TFileStream und binäre Daten
Ich muss eine Datei binär einlesen, einzelne Bytes ändern und dann wieder in einer Datei speichern.
Leider scheitere ich bereits am Einlesen, obwohl ich ausgiebig im Forum gesucht habe:
Delphi-Quellcode:
Wenn ich das ganze mit einem statischen ByteArray mache, funktioniert es seltsamerweise korrekt. Aber ich weiß doch zum Entwurfszeitpunkt noch nicht, wie groß die zu lesende Datei ist.
procedure TEKG.ReadStream(const SelectedRoot, SelectedFile: string);
var s: string; i, BUFFERSIZE: integer; ByteArray: array of byte; begin //Dateigröße feststellen with tfilestream.create(SelectedRoot + SelectedFile ,fmopenread or fmShareDenyNone) do try size; BUFFERSIZE := Size; finally Free; end; //Arraygröße festlegen SetLength(ByteArray, BUFFERSIZE); i := 0; with TFileStream.Create(SelectedRoot + SelectedFile, fmOpenRead) do try Read(ByteArray, BUFFERSIZE); finally Free; end; //zum testen der Funktion lesbare Zeichen in Char umwandeln und in Memo1 anzeigen for i := 1 to BUFFERSIZE do begin if ByteArray[i] in [65..90, 97..122, 196, 214, 220, 228, 246, 252] then s := s + Char(ByteArray[i]) end; Memo1.text := s; end; Wer kann mir weiterhelfen und auch gleich sagen, wie ich anschließende zum Beispiel das Byte ByteArray[249] in die Zahl 09 ändere und das ganze in eine neue oder diesselbe Datei speichere? Vielen Dank |
Re: TFileStream und binäre Daten
Man muss nicht die gesamte Datei in einem Rutsch bearbeiten. Mit
Delphi-Quellcode:
kann man solange z. B. 4 KB lesen, bis das Ende der Datei erreicht ist. Noch einfacher wird's, wenn man nicht wieder in den gleichen Stream zurück schreiben muss (z. B. mit Backup). Dann kann man folgendes Schema anwenden:
while Stream.Position < Stream.Size do
P.S.: Speicher den Stream doch in einer Variable, anstatt ihn zweimal zu erschaffen |
Re: TFileStream und binäre Daten
Hallo Ralf,
abgesehen von Phistevs Ratschlägen habe ich deinen Code etwas überarbeitet. Was dir unbekannt vorkommt, kannst du dir mit der kontextsensitiven Hilfe von Delphi bestimmt erarbeiten.
Delphi-Quellcode:
Grüße vom marabu
procedure TEKG.ReadStream(const SelectedRoot, SelectedFile: string);
var s: string; i: integer; ba: array of byte; fs: TFileStream; begin // Datei öffnen fs := TFilestream.Create(SelectedRoot + SelectedFile ,fmopenread or fmShareDenyNone); // Puffer an Dateigröße anpassen SetLength(ba, fs.Size); // Datei komplett in Puffer einlesen fs.Read(ba[0], Length(ba)); // Datei wieder freigeben fs.Free; // Leeren String bereit stellen s := ''; // Jedes Byte im Puffer anschauen for i := Low(ba) to High(ba) do // Steuerzeichen ausklammern if (ba[i] > 32) and (ba[i] <> 127) then s := s + Chr(ba[i]) else s := s + ' '; // String an Memo zur Anzeige übergeben Memo.Text := s; end; |
Re: TFileStream und binäre Daten
Marabus Code funktioniert einwandfrei, vielen Dank
Jetzt habe ich versucht, wie ich den stream wieder in die Datei zurückschreiben kann, mein kläglicher Versuch erzeugt aber nur ein (fast) leeres File:
Delphi-Quellcode:
Mit fs.Write(ba, Length(b)) bekomme ich eine Datei mit völlig zerstörten Daten zurück
procedure TEKG.WriteStream(const SelectedRoot, SelectedFile: string);
var fs: TFileStream; i: integer; s: string; begin fs := TFileStream.Create(SelectedRoot + SelectedFile, fmCreate); try i := length(ba); fs.Write(i, sizeOf(i)); finally fs.Free; end; end; Was mache ich denn schon wieder falsch Ralf |
Re: TFileStream und binäre Daten
ba[0] bzw. ba[1] statt ba. i ist nur ein Integer (4 Byte)
|
Re: TFileStream und binäre Daten
Danke, jetzt funktioniert alles korrekt. Das Thema kann von meiner Seite daher gerne abgeschlossen werden
Ralf |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz