![]() |
Dynamische Arrays vom Type Byte in Verbindung mit TFileStream
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,
ich habe ein Problem mit Dynamische Arrays vom Type Byte in Verbindung mit dem Lesen eines TFileStreams. Ich benutze Delphi 5 und habe die Testdatei hier mit hochgeladen. Nach dem öffnen einer Binärdatei mittels TFileStream versuche ich diese in seine Bestandteile zu zerlegen. Dazu lese ich die ersten 9 Bytes ein und speichere Sie in ein Statisches Array des Types Byte. Das funktioniert auch. Das 6 und 7 Byte multipliziert mit dem 8 und 9 Byte ergibt dann die Anzahl an Bytes die danach eingelesen werden sollen. Dazu verwende ich dann mein dynamisches Arrays und setze die Länge. Am Ende lese ich dann exakt soviele Bytes wie in das dynamische Array reinpassen würden was zur Folge hat, dass eine Exception ausgelöst wird und ich weiß nicht weshalb.
Delphi-Quellcode:
Wenn ich ein statisches Array benutze wird keine Exepction auslöst und die Daten im Array wurden korrekt eingelesen.
procedure TForm1.Button2Click(Sender: TObject);
Var floFStream : TFileStream; a : Array [ 1 .. 9 ] of byte; b : Array of byte; breite,hoehe : Integer; l : Integer; begin mpoOut.Clear; OpenDialog1.InitialDir := zgvExec; if Not OpenDialog1.Execute Then Exit; floFStream := TFileStream.Create(OpenDialog1.FileName, fmOpenReadWrite); Try floFStream.ReadBuffer(a,9); breite := a[6] + a[7]*256; // = 112 hoehe := a[8] + a[9]*256; // = 112 l := breite * hoehe; // = 12544 SetLength(b,l); ShowMessage( IntToStr(High(b) )); // = 12543 da dynamische Arrays mit dem Index 0 beginnen floFStream.ReadBuffer(b,l); // Exception: Stream-Read-Fehler. Finally floFStream.Free; End; end;
Delphi-Quellcode:
Ich habe mich jetzt mittels Google auf diversen Seiten, Tutorials und Foren getummelt und auch meine Delphi Bücher zu rate gezogen aber ich finde einfach nicht den Grund.
procedure TForm1.Button2Click(Sender: TObject);
Var floFStream : TFileStream; a : Array [ 1 .. 9 ] of byte; c : Array [ 0 .. 12543 ] of byte; breite,hoehe : Integer; l : Integer; begin mpoOut.Clear; OpenDialog1.InitialDir := zgvExec; if Not OpenDialog1.Execute Then Exit; floFStream := TFileStream.Create(OpenDialog1.FileName, fmOpenReadWrite); Try floFStream.ReadBuffer(a,9); breite := a[6] + a[7]*256; // = 112 hoehe := a[8] + a[9]*256; // = 112 l := breite * hoehe; // = 12544 floFStream.ReadBuffer(c,12544); // keine Exception Finally floFStream.Free; End; end; Nun hoffe ich darauf, dass jemand von euch eine Erklärung oder zumindest einen weiteren Denkanstoß parat hat. Ich würde alternativ ein statisches Array der Größe 1 des Types Bytes benutzen, und dann mittels schleifen den Filestream Byte für Bytes auslesen und dann in ein dynamische Array vom Type ShortInt o.ä. rüberschaufeln was aber eher eine unglückliche Lösung wäre (getestet habe ich es auch noch nicht, da es für mich der Worst Case wäre). Schönes Wochenende noch Thomas |
AW: Dynamische Arrays vom Type Byte in Verbindung mit TFileStream
Ein dynamisches Array ist intern ein Pointer auf das Array. Deswegen geht das nicht:
Delphi-Quellcode:
floFStream.ReadBuffer(b,l); // Exception: Stream-Read-Fehler.
weil du damit den Pointer überschreibst, aber das geht:
Delphi-Quellcode:
floFStream.ReadBuffer(b[0],l);
|
AW: Dynamische Arrays vom Type Byte in Verbindung mit TFileStream
Ah es geht! Hurra!
Man kann also mit dem Low Index eines Arrays das gesamte Array füllen? Als ich deine Antwort gesehen habe, dachte ich zuerst es würde nur ein Byte in das Array geschrieben werden. Vielen Dank für deine Antwort! Das bring mich richtig weiter in meinem Programm. |
AW: Dynamische Arrays vom Type Byte in Verbindung mit TFileStream
Ein Array besteht aus einem Zeiger/Pointer auf seine Daten.
Und da liegen ab dem ersten Feld alle Felder direkt hintereinander und vor dem ersten Eintrag versteckt sich ein Integer für die Arraygröße. Also ja. Statt dem Array kannst du auch einen TMemoryStream verwenden, bzw. eeinen TByteStream (in aktuelleren Delphis), wo du die Daten via TStream.CopyFrom vom TFileStream kopieren, aber dennoch über einen Pointer drauf zugreifen könntest. |
AW: Dynamische Arrays vom Type Byte in Verbindung mit TFileStream
danke für die Erklärungen. Jetzt weiß ich nicht nur wie es funktioniert sondern auch warum ;-)
|
AW: Dynamische Arrays vom Type Byte in Verbindung mit TFileStream
Rein aus Interesse:
Wenn ich das richtig verstanden habe, dann müsste auch
Delphi-Quellcode:
floFStream.ReadBuffer(Pointer(b)^,l);
gehen, oder liege ich da falsch? Falls noch jemand die Geduld hat mir diese Fragen zu beantworten : Was ist dann der Unterschied wenn das Feld b statisch ist? D.h. was passiert bei einem Zugriff á la
Delphi-Quellcode:
?
floFStream.ReadBuffer(b,l);
Grüße! |
AW: Dynamische Arrays vom Type Byte in Verbindung mit TFileStream
Jupp, das mit dem Pointer ginge praktisch auch.
Aber wenn du über das feld gehst, dann ist es egal, ob es eine dynamisches oder statisches Array ist. > unterschiedliche Typen, aber gleicher/einheitlicher Code Beim dynamischen Array muß man nur bei Einwas aufpassen. Wenn die Bereichsprüfung aktiv ist und man greift auf das Feld 0 eines leeren Arrays zu, dann kommt rein rechnerisch immernoch NIL raus, aber die Bereichsprüfung knallt da, weil es das feld 0 natürlich nicht gibt. Ein statisches Array ist praktisch wie ein Record, in dem alle Felder hintereinander stehen. Also ohne den Pointer und ohne die Längen-Info vor den Daten. Die Längen-Info steht da dann ja in der RTTI. |
AW: Dynamische Arrays vom Type Byte in Verbindung mit TFileStream
Dankeschön
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:39 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 by Thomas Breitkreuz