![]() |
array of byte (dynamisch) schreiben in FileStream
Hi,
irgendwie bekomme ich es nicht auf die Reihe ein dynamisches Array of Byte per Filestream in eine Datei zu schreiben. Ich habe ein dynamische Array welches ich per SetLength auf die Größe setze. Dann fülle ich das gesamte Array einfach mal mit $55. Bei Prüfung ist auch jedes Byte = $55 nun per fs.Write in den Filestream geschrieben und nachher in die Datei geschaut sind dort keine $55 sondern irgendwelcher Datenmüll. Irgendwie machen mich Pointer immer ganz irre :???: Habe mal ein Beispiel kurz zusammengebaut:
Delphi-Quellcode:
Der Source ist einfach auf das Minimum reduziert, daher mag es etwas unsinnig erschreinen wenn ich einfach den Anfang einer Datei mit $55 überschreibe, aber es geht mir nur um den .write Vorgang.
const BUFSIZE = 1024;
begin Fs := TFileStream.Create(fn, fmOpenReadWrite); try SetLength(ContentBlk, BUFSIZE); for i:=low(ContentBlk) to high(ContentBlk) do ContentBlk[i] := $55; Fs.Seek(0, soFromBeginning); Fs.Write(ContentBlk, BUFSIZE); FlushFileBuffers(Fs.Handle); finally Fs.Free; end; end; |
Re: array of byte (dynamisch) schreiben in FileStream
Achtung: Ein dynamisches Array ist im Gegensatz zu einem statischen ein Referenztyp.
=>
Delphi-Quellcode:
Fs.Write(ContentBlk[0], BUFSIZE);
|
Re: array of byte (dynamisch) schreiben in FileStream
Hi,
also den wichtigsten Tip hast du schon bekommen, aber du solltest noch ein paar Kleinigkeiten ändern. Dein FS.Create sollte schon in den try ... finally Block rein. Dann ist es sicherlich schlecht, wenn jmd. anderes die datei auch noch schreiben kann während du an der arbeitest (fmOpenReadWrite or fmShareDenyWrite). Um ein Array schnell mit einem Wert zu füllen (kann ja sein das du auch später einen hast), einfach FillChar benutzen. Also etwas wie
Delphi-Quellcode:
Gruß Der Unwissende
const BUFSIZE = 1024;
begin try Fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyWrite); setLength(ContentBlk, BUFSIZE); FillChar(ContentBlk[0], length(ContenBlk), $55); Fs.Seek(0, soFromBegining); Fs.Write(ContentBlk[0], BUFSIZE); finally Fs.Free; end; end; |
Re: array of byte (dynamisch) schreiben in FileStream
Super, danke das war es schon und wieder was gelernt.
Herjehhh und das in einem Forum binnen 30min, Leute Ihr seit super. :dancer: Wünsche frohe :xmas: |
Re: array of byte (dynamisch) schreiben in FileStream
Zitat:
|
Re: array of byte (dynamisch) schreiben in FileStream
Hi,
ok, würdest du bekommen wenn Fs lokal deklariert wäre, hier glaube ich nicht der Fall. Wenn es eine Klassenvariable ist, dann würde Fs nil sein und damit dürfte Free keine Exception auslösen. Aber gut, hast schon recht, aber um es wirklich sauber zu machen, solltest du immer darauf achten, dass die Erstellung eines FileStreams scheitern kann. Du solltest also mit einer Exception rechnen (z.B. fehlende Lese/Schreibrechte) und das ganze abfangen. Dann natürlich eher:
Delphi-Quellcode:
const BUFSIZE = 1024;
begin try Fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyWrite); try setLength(ContentBlk, BUFSIZE); FillChar(ContentBlk[0], length(ContenBlk), $55); Fs.Seek(0, soFromBegining); Fs.Write(ContentBlk[0], BUFSIZE); finally Fs.Free; end; except // was auch immer end; end; |
Re: array of byte (dynamisch) schreiben in FileStream
@Der_Unwissende: über SEH gibt es durchaus geteilte Meinungen, und wir beide scheinen nicht die selbe zu haben :???:
Zitat:
Zitat:
Gerade so einen Tipp interpretieren Anfänger (dazu zähle ich dich nach deinen zahlreichen anspruchsvollen Beiträgen übrigens absolut nicht) oftmals vollkommen falsch. Was dann aus so einem Stück Code wird ist oft (jetzt mal den Ansatz von oben umgedreht -> Einlesen von Daten):
Delphi-Quellcode:
Was hat man in diesem Fall durch das try...except gewonnen: nichts!
var
k, BufLen: integer; Buffer: array of Byte; begin try FS := TFileStream.Create(fn, fmOpenRead or fmShareDenyWrite); try FS.ReadBuffer(BufLen, SizeOf(BufLen)); SetLength(Buffer, BufLen); FS.ReadBuffer(Buffer[0], BufLen); finally FS.Free; end; except MesssageDlg('Fehler'); end; // und hier arbeitet man munter lustig weiter, als ob nichts geschehen wäre for k := 0 to BufLen - 1 do begin if Buffer[k] = $55 then ...; end; end;
Persönlich verwende ich try..except fast ausschließlich für die folgenden Fälle: 1. Als erweiterten Ressourcenschutz wo try..finally nicht funktioniert. Beispiel:
Delphi-Quellcode:
2. Für Prüfungen. Beispiel:
Result := TKlasse.Create;
try ... except on E: Exception do begin Result.Free; raise; end; end;
Delphi-Quellcode:
3. Als Schutz vor Fehlern in Fremdkomponenten, die man selbst weder debuggen noch korrigieren kann.
try
... Result := true; except on E: MeineErwarteteExceptionBeiFalschemFormat do Result := false; else raise; end; SEH ist aber, wie oben schon geschrieben, ein durchaus kontrovers diskutiertes Thema (siehe u.a. ![]() |
Re: array of byte (dynamisch) schreiben in FileStream
Zitat:
Zitat:
Ich wollte eigentlich nur vorwarnen, dass so ein Fehler einem Anfänger natürlich ruhig vom Programm geschmissen werden kann, aber gerade wenn es ein fertiges Produkt (gut, hier sicherlich nicht der Fall) wird, dann sollte man doch lieber Fehler behandeln. Wo ich dir total recht gebe ist natürlich, dass es unbedingt eine sinnvolle Behandlung sein sollte! Hatte auch schon mal ein super Schrittmotor, der mir von seinen 58 Fehlercodes einen lieferte, der allerdings besagte Error. War ich auch begeistert, dass der Fehler Fehler aufgetreten ist. Also Leute entweder garnicht abfangen oder was Richtiges (womit ich hoffentlich Flocke's Meinung bin). Also im Zweifel gar nicht. Insbesondere nie leeres except! Nichtmal wenn man glaubt das es unerreichbar ist. Gruß Der Unwissende |
Re: array of byte (dynamisch) schreiben in FileStream
Zitat:
Diesbezüglich kommt mir noch eine grundlegende Frage wieder in den Sinn. Wie sieht es bez. geschützter Blöcke denn aus mit der Programmperformance? |
Re: array of byte (dynamisch) schreiben in FileStream
Bezog sich nicht auf dich, wollte hier nur kurz erklären warum ich hier den try.. except Block noch gesetzt hatte (und man es so nicht machen sollte). Gibt halt nur immer gern andere die es noch lesen und dann halt wirklich einen leeren Block setzen und das ist miserabler Codestil und verdammt nervige Fehlersuche.
Was die Performance angeht, so solltest du einfach nicht jede Zeile Code in einen geschützten Block setzen. Nicht weil die Performance dabei einbricht, sondern weil es sinnfrei wäre (gehe nicht davon aus, dass das jmd. tut). Die Objekte bei denen man geschützte Blöcke verwendet (gibt ja wirklich nicht so viele), sind eh meistens langsamer als dein Systemtakt, da kommt es auf das überprüfen eines Flags und einem möglichen Sprung mehr oder weniger auch nicht an. Die Vorteile überwiegen einfach den Performanceverlust (den du nicht merken würdest) bei weitem. Allerdings halt auch nur bei sinnvoll gesetzten try ... except ... finally Blöcken. Und wenn du einen Fehler beim lesen eines z.B. MemoryStreams hast und dann den allozierten Speicher nicht wieder frei gibst, ist der Fehlende Speicher schon viel schlechter für die Performance. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:36 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