AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Daten mit AssignFile ändern oder anfügen
Thema durchsuchen
Ansicht
Themen-Optionen

Daten mit AssignFile ändern oder anfügen

Ein Thema von Ralf Stehle · begonnen am 31. Okt 2005 · letzter Beitrag vom 31. Okt 2005
Antwort Antwort
Ralf Stehle

Registriert seit: 8. Aug 2003
124 Beiträge
 
Delphi 7 Professional
 
#1

Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 12:28
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:
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.
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

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
Ralf Stehle
ralfstehle@yahoo.de
  Mit Zitat antworten Zitat
ichbins

Registriert seit: 9. Jul 2005
Ort: Hohenaltheim
1.001 Beiträge
 
Delphi 2005 Personal
 
#2

Re: Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 12:37
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
for i:=23430 to 180 do begin kann gar nicht gehen, da er nicht von 23430 bis 180 HOCHzählen kann. Du musst statt to downto nehmen.

An die Datei anhängen geht auch mit blockwrite.

Um ans Ende einer Datei zu springen, machst du

  seek(f,filesize(f)); was die For-Schleife macht, weiss ich jetzt nicht? In BUF sind ja nur die ersten 2048 Bytes der Datei gespeichert...
Wie kannst du dann auf das Byte nr.23430 zugreifen? da kommt doch eh ein Fehler?
Michael Enßlin
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#3

Re: Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 12:59
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
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#4

Re: Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 13:02
Mit einem FileStream würde es etwa so funktionieren:

Delphi-Quellcode:
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;
Grüße vom marabu
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 13:12
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?
  Mit Zitat antworten Zitat
Ralf Stehle

Registriert seit: 8. Aug 2003
124 Beiträge
 
Delphi 7 Professional
 
#6

Re: Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 13:37
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
Ralf Stehle
ralfstehle@yahoo.de
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#7

Re: Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 13:41
Ok, hier mal mit MemoryStream

Delphi-Quellcode:
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;
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!
Natürlich sollte die 23430 auch als CONST definiert werden, macht Änderungen schöner, wie gesagt guck erstmal

Gruß Der Unwissende
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#8

Re: Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 13:49
Hallo Unwissender,

Zitat von Der_Unwissende:
kann ich Pos > Size setzen? ... Und war Size sogar ein Property mit write?
sogar das geht: klick

Freundliche Grüße vom marabu
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#9

Re: Daten mit AssignFile ändern oder anfügen

  Alt 31. Okt 2005, 14:17
@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ß
  Mit Zitat antworten Zitat
Antwort Antwort


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 05:51 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