![]() |
Daten mit AssignFile ändern oder anfügen
Ich möchte an einer ganz bestimmten Stelle einer Binärdatei Daten einfügen. Falls diese Daten schon vorhanden sind, sollen Sie überschrieben werden, falls die Daten nicht vorhanden sind, müssen Sie ans Ende der Datei angehängt werden
Mit AssignFile habe ich es immerhin schon geschafft, eine Datei zu kopieren und dabei die Daten zu ändern:
Delphi-Quellcode:
Falls die Dateiposition 23430 (und die Bytes danach) nicht vorhanden sind, soll der Inhalt von Edit1.Text genau an der Position 23430 drangehängt werden
var Buffer: array[1..2048] of byte;
NumRead, NumWritten, i : Integer; q,z: File; s: string; c: char; begin AssignFile(q, SelectedRoot + SelectedFile,'.001')); Reset(q, 1); AssignFile(z, SelectedRoot + SelectedFile,'.002')); Rewrite(z, 1); BlockRead(q, Buffer, SizeOf(Buffer), NumRead); for i:=23430 to 180 do begin s := Copy(EditNachname.Text, i-23430, 1); if s='' then Buffer[i]:= 0 else Char(Buffer[i]):= s[1] end; BlockWrite(z, Buffer, NumRead, NumWritten); repeat BlockRead(q, Buffer, SizeOf(Buffer), NumRead); BlockWrite(z, Buffer, NumRead, NumWritten); until (NumRead = 0) or (NumWritten <> NumRead); CloseFile(q); CloseFile(z); end. Ich schaffe das leider nicht ohne eure Hilfe, da ich eigentlich nicht genau verstehe, was Numread und NumWritten in der Repeat-Schleife genau bewirken Vielen Dank Ralf |
Re: Daten mit AssignFile ändern oder anfügen
numread und numwrite sind zwei Variablen, in die gespeichert wird, wie viele Bytes tatsächlich gelesen oder geschrieben wurden. Die kannste auch weglassen, aber dann kommt ne Exception wenn er nicht so viele Bytes schreiben/lesen kann wie du ihm sagst.
Die Schleife
Delphi-Quellcode:
kann gar nicht gehen, da er nicht von 23430 bis 180 HOCHzählen kann. Du musst statt to downto nehmen.
for i:=23430 to 180 do begin
An die Datei anhängen geht auch mit blockwrite. Um ans Ende einer Datei zu springen, machst du
Delphi-Quellcode:
was die For-Schleife macht, weiss ich jetzt nicht? In BUF sind ja nur die ersten 2048 Bytes der Datei gespeichert...
seek(f,filesize(f));
Wie kannst du dann auf das Byte nr.23430 zugreifen? da kommt doch eh ein Fehler? |
Re: Daten mit AssignFile ändern oder anfügen
Hey,
ich glaube du kannst das alles viel leichter realisieren, indem du auf AssignFile verzichtest und ein TMemoryStream-Objekt benutzt. Da hast du einen Zeiger auf Memory, was halt wirklich der Speicherbereich ist, den du möchtest. Ein TStream hat immer eine Größe (size) mit der du gleich weißt, wie groß deine Datei ist (und ist auch noch schnell). Mein Ansatz wäre es, dass du dir ein solches TMemoryStream Objekt anlegst. Dann noch ein Array dyn. Größe, dass setzt du auf das Maximum von der reelen Dateigröße und der Größe, die eine Datei hätte wenn du deine Bytes schreibst und dann kopierst du mit CopyMememory (WindowsApi) einfach den inhalt der Datei in dieses Array. In diesem Array änderst du die Stellen, die du ändern möchtest und schreibst das Array einfach in den Stream (den Inhalt vorher löschen oder ab Position := 0 schreiben). Hab leider gerade kein Delphi da und kann dir nicht wirklich ein Bsp. schicken, aber vielleicht später, hoffe ist grob klar? Sonst einfach nochmal fragen. Gruß Der Unwissende |
Re: Daten mit AssignFile ändern oder anfügen
Mit einem FileStream würde es etwa so funktionieren:
Delphi-Quellcode:
Grüße vom marabu
procedure WriteString(fileName, s: string; pos: cardinal);
begin if FileExists(fileName) then with TFileStream.Create(fileName, fmOpenWrite, fmShareDenyWrite) do begin Position := pos; Write(s[1], Length(s)); Free; end; end; |
Re: Daten mit AssignFile ändern oder anfügen
Weil ich mir gerade nicht sicher bin, kann ich Pos > Size setzen? Müsste ich glatt mal in die Hilfe schauen, klingt so unsauber. Und war Size sogar ein Property mit write?
|
Re: Daten mit AssignFile ändern oder anfügen
Vielen Dank für die Tipps, die Idee mit dem Filestream muss ich mal probieren, sieht ja recht logisch aus.
Die Schleife for i:=23430 to 180 war ein Tippfehler, es sollte heißen for i:=23430 to Length(Edit1.text), ich wollte nur zeigen, dass ich genau am Byte 23430 die Zeichen einfügen möchte |
Re: Daten mit AssignFile ändern oder anfügen
Ok, hier mal mit MemoryStream
Delphi-Quellcode:
Gut, für max brauchst du die Unit Math und FILENAME musst du natürlich anpassen. An sich kann man da sicher noch einiges sauberer und schöner machen, ab guck erstmal ob es das ist was du möchtest. Insbesondere solltest du buffer natürlich mit 0en oder etwas anderem Definiertem füllen, denn sonst kann es natürlich sein dass da etwas unerwartetes steht und bei irgendeiner Auswertung mal nicht egal ist. Wie gesagt, es würden jetzt auch alle Daten die schon drin standen beibehalten werden. Das heißt natürlich auch, dass wenn du schon einen längeren Edit1.Text z.B. '123' abgespeichert hast und den mit '45' überschreibst stünde in der Datei ab 23430 '453', die würde also nicht überschrieben werden!
var MemoryStream : TMemoryStream;
buffer : Array of Byte; begin // Memorystream anlegen MemoryStream := TMemoryStream.Create; // Datei laden MemoryStream.LoadFromFile(FILENAME); // Maximum aus schon existierender Dateigröße und Datei mit 23430 Byte + // Länge des angehangenen Textes setLength(buffer, max(23430 + length(self.Edit1.Text), MemoryStream.Size)); // kopieren der schon vorhandenen bytes aus der Datei if MemoryStream.Size > 0 then begin copyMemory(@buffer[0], MemoryStream.Memory, MemoryStream.Size); end; // if size(MemoryStream) > 0 // schreibt Edit1.Text an die Stelle 23430 (also beginnend bei) // überschreibt auch alles was schon vorhanden ist copyMemory(@buffer[23430], PChar(self.Edit1.Text), length(self.Edit1.Text)); // löschen der alten Daten und rücksetzen der Position im Stream MemoryStream.Clear; // schreibt alle erzeugten Daten MemoryStream.Write(buffer[0], length(buffer)); // abspeichern MemoryStream.SaveToFile(FILENAME); // aufräumen MemoryStream.Free; Natürlich sollte die 23430 auch als CONST definiert werden, macht Änderungen schöner, wie gesagt guck erstmal Gruß Der Unwissende |
Re: Daten mit AssignFile ändern oder anfügen
Hallo Unwissender,
Zitat:
![]() Freundliche Grüße vom marabu |
Re: Daten mit AssignFile ändern oder anfügen
@marabu Hey, praktisch, danke. Hab es mir gerade in der etwas na ja formulierten Hilfe angeschaut, da steht dass die Zuweisung bei TStream wirkungslos ist und bei abgeleiteten Klassen überschrieben werden kann, toll. Heißt das nicht letztlich, dass man es je nach Ableitung probieren muss? Geh aber jetzt davon aus, dass alle bekannten Ableitungen (insbesondere TFile- und TMemorystream) das können.
Gruß |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:23 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