![]() |
Fehler bei TFileStream.ReadBuffer mit Buffer size
Hallo Forum,
ich habe ein Problem mit meinem FileStream, das ich mir nicht erklären kann. Ich möchte aus einer 40 byte großen Datei die ersten 9 byte in einen Buffer einlesen. Hier ist mein Code:
Delphi-Quellcode:
Auf die Datei wird sonst nirgendwo im Code zugegriffen, sie liegt fest im Projektverzeichnis und wird nicht verändert.
procedure Test;
var buf: array of byte; buf_headsize: integer; FS: TFileStream; const FN: String = '.\Test.dat'; begin FS := TFileStream.Create(FN, fmOpenReadWrite); buf_headsize := 9; if (FS.Size >= buf_headsize) then begin // FS.Size = 40 SetLength(buf, buf_headsize); showmessage(inttostr(High(buf))); // liefert 8 try FS.Seek(0, soFromBeginning); FS.ReadBuffer(buf, buf_headsize); // manchmal gibt es hier schon eine Exception finally showmessage(inttostr(High(buf))); // lieferte schonmal -1, auch Werte wie 12 oder 9095 wurden hier angezeigt - brachte auch schon Exceptions end; end; end; Der FileStream wird auch korrekt initialisiert, immerhin ist ja der Wert FS.Size = 40 abrufbar. Durch FS.ReadBuffer dürfte sich doch außer dem Inhalt des Arrays nicht ändern, die Größe sollte doch gleich bleiben? Kann sich diesen Fehler (Kommentare im Code) jemand erklären? NACHTRAG: ich habe jetzt versucht, das Array buf mit fester Länge zu erzeugen:
Delphi-Quellcode:
So tritt kein Fehler auf. Allerdings wäre mir ein dynamisches Array sehr viel lieber, da ich es danach noch weiterverwenden möchte.
var buf: array [0..8] of byte;
Vielen Dank wie immer für eure Hilfe, Gruß Xoric |
AW: Fehler bei TFileStream.ReadBuffer mit Buffer size
Schreib das mal so:
Delphi-Quellcode:
FS.ReadBuffer(buf[0], buf_headsize);
|
AW: Fehler bei TFileStream.ReadBuffer mit Buffer size
Delphi-Quellcode:
.
FS.ReadBuffer(buf, ...
Dieses überschreibt die "Variable" und bei einem dynamischen Array oder String ist die Variable intern ein Zeiger. Du überscheibts also den Zeiger, welcher aktuell nur 4 Byte groß ist und danach werden frende Daten oder nichtreservierte Speicherbereiche überschrieben (entspricht einem Buffer-Overrun). Du willst aber die "Array-Daten" überschreiben. also entweder das buf[0] um das erste Byte des Arrays zu referenzieren oder du brauchst eine andere "nichtzeiger"-Variable, wie z.B. ein statisches Array.
Delphi-Quellcode:
var buf: array of byte;
SetLengeh(buf, 9) FS.ReadBuffer(buf[0], 9);
Delphi-Quellcode:
var buf: array[0..8] of byte;
SetLengeh(buf, 9) FS.ReadBuffer(buf, 9); // wobei hier ein dereferenzieren nicht schaden kann var buf: array[0..8] of byte; FS.ReadBuffer(buf[0], 9); var buf: array[1..9] of byte; FS.ReadBuffer(buf, 9); // FS.ReadBuffer(buf[1], 9); |
AW: Fehler bei TFileStream.ReadBuffer mit Buffer size
Die Funktion Low kann bei solchen Spielchen auch helfen, dass man nicht plötzlich, wenn man von dynamisch auf statisch (und bei 1 beginnend) umsteigt o.ä., Probleme bekommt :-D
|
AW: Fehler bei TFileStream.ReadBuffer mit Buffer size
Hallo ihr drei!
Durch die kleine Änderung im Code funktioniert es jetzt einwandfrei. Bisher hatte ich tatsächlich nur statische Arrays verwendet und habe mit
Delphi-Quellcode:
nie Probleme bekommen.
FS.ReadBuffer(buf, sizeof(buf));
Warum das so ist, hab ich dank euch jetzt verstanden. In Zukunft werde ich mir also
Delphi-Quellcode:
angewöhnen.
FS.ReadBuffer(buf[0], sizeof(buf));
Vielen Dank an euch Deep-Sea, sx2008 und himitsu für die umfangreiche Erklärung :) Ein schönes Wochenende! Gruß Xoric |
AW: Fehler bei TFileStream.ReadBuffer mit Buffer size
Was Deep-Sea noch meinte war das:
Delphi-Quellcode:
.
FS.ReadBuffer(buf[Low(buf)], ...)
Das nimmt sich dann immer den Anfang des Arrays, egal wie es definiert ist. Aber ich schreibe auch fast immer die [0] hin, da es sich sowieso besser macht, Arrays einheitlich zu deklarieren. (nur bei einigen Sonderfällten macht sich ein einfacher Array-Anfang manchmal besser ... bei mir sind das z.B. Arrays, welche paralell zu Strings verarbeitet werden, welche dann mit [1..] beginnen, damit auch da die Zählung einheitlich ist) |
AW: Fehler bei TFileStream.ReadBuffer mit Buffer size
Zitat:
Delphi-Quellcode:
.
FS.ReadBuffer(buf[0], length(buf)*sizeof(buf[0]))
|
AW: Fehler bei TFileStream.ReadBuffer mit Buffer size
Oh richtig ;)
Bei dynamischen Arrays ist das ja die Größe des Pointers. Ich hab die Größe des Buffers sowieso wie oben immer in einer Variable abgelegt. Danke für den Hinweis gammatester! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 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