![]() |
Re: StreamWrite erzeugt nur 0 Byte-File
WriteBuffer hat den Vorteil, dass man sich selbst um nichts kümmern muss.
WriteBuffer erzeugt eine Exception, wenn das Zielmedium die Daten nicht aufnehmen kann (z.B. Platte voll oder Schreibfehler wg. defektem Sektor)
Delphi-Quellcode:
Deshalb empfehle ich WriteBuffer anstelle von Write zu verwenden.
procedure TStream.WriteBuffer(const Buffer; Count: Longint);
begin // wenn Count=0 ist, passiert gar nichts // andernfalls werden Count Bytes geschrieben if (Count <> 0) and (Write(Buffer, Count) <> Count) then // falls beim Schreiben ein Fehler aufgetreten ist, wird eine Exception erzeugt raise EWriteError.CreateRes(@SWriteError); end; |
Re: StreamWrite erzeugt nur 0 Byte-File
Nun gut, dann umgestellt um die Exception von WriteBuffer() zu nutzen...
Delphi-Quellcode:
Ja, wieder im Beitragseditor geschrieben und ungetestet. Also keine Schläge, wenn wieder Kleinigkeiten falsch sind...
function DateiSchreiben(const AFilename: string; const AFileSize: Int64): boolean;
const coBlockSize = 16384; var lStream: TStream; lFileData: string; lBytesToWrite: Int64; lWriteCount: Int64; begin result := false; // Erstmal den Stream öffnen. Wenn das nicht klappt, brauch ich kein Array... lStream := TFileStream.Create(AFilename, fmCreate or fmShareDenyWrite); try lFileData := StringOfChar(#55, coBlockSize); lBytesToWrite := AFileSize; while ( lBytesToWrite > 0 ) do begin lWriteCount := Min(lBytesToWrite, coBlockSize); lStream.WriteBuffer(lFileData[1], lWriteCount); Dec(lBytesToWrite, lWriteCount); end; result := true; finally lStream.free; end; end; |
Re: StreamWrite erzeugt nur 0 Byte-File
Ja, das war wohl der ausschlaggebende Punkt.
Nun habe ich aber das Problem, nicht etwa einen String wie lFileData mit identischen Zeichen (hier #55, also die Ziffer 7), sondern einem Testmuster schreiben zu wollen. Hierfür habe ich ein 64 Zeichen großes Muster defininiert:
Delphi-Quellcode:
Wenn ich nun aber TestMuster anstatt von lFileData[1] in der Write-Funktion verwende, wird das Muster nur einmal geschrieben, und der Rest ist Datensalat. Wie könnte man das Beispiel denn abändern, so dass dieses Testmuster fortlaufend geschrieben wird ? Mit 64 Byte kann ich da bspw. Dateigrößen von 1, 4 oder 16 MByte abdecken, da diese durch 64 ohne Rest teilbar sind.
CONST TestMuster = '#abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+';
|
Re: StreamWrite erzeugt nur 0 Byte-File
Der jetzige Code deckt alle Dateigrößen ab, auch ungerade :warn:
Delphi-Quellcode:
Wieder ungetestet, aber sollte so klappen.
function DateiSchreiben(const AFilename: string; const AFileSize: Int64): boolean;
const coFileData = '#abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+'; var lStream: TStream; lBytesToWrite: Int64; lWriteCount: Int64; begin result := false; // Erstmal den Stream öffnen. Wenn das nicht klappt, brauch ich kein Array... lStream := TFileStream.Create(AFilename, fmCreate or fmShareDenyWrite); try lBytesToWrite := AFileSize; while ( lBytesToWrite > 0 ) do begin lWriteCount := Min(lBytesToWrite, length(coFileData)); lStream.WriteBuffer(coFileData, lWriteCount); Dec(lBytesToWrite, lWriteCount); end; result := true; finally lStream.free; end; end; |
Re: StreamWrite erzeugt nur 0 Byte-File
Danke, das Beispiel funktioniert einwandfrei.
Nun habe ich bspw. den Fall, die zuvor geschriebenen Testmusterdaten wieder lesen und überprüfen zu wollen, wozu ich einerseits die Create-Zeile wiefolgt abändere:
Delphi-Quellcode:
und andererseits eine lokale Stringvariable namens ReadMuster deklariere sowie ReadBuffer einsetze:
lStream := TFileStream.Create(AFilename, fmOpenRead);
Delphi-Quellcode:
Beim Debuggen wird diese Funktion auch durchgeführt, aber ich kann auf den String ReadMuster nicht zugreifen (hier erscheint eine Exception). Das beginnt mit der IF-Abfrage direkt nach ReadBuffer. Wie kann man das am besten lösen ?
CONST TestMuster = '#abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+';
VAR ReadMuster : STRING; BEGIN ... DateiStream.ReadBuffer(ReadMuster, lReadCount); IF ReadMuster <> TestMuster THEN ShowMessage('Gelesenes Muster stimmt nicht mit dem Testmuster überein.'); ... |
Re: StreamWrite erzeugt nur 0 Byte-File
Der String ist leer. Setze die entsprechende Stringlänge bevor du was einliest.
![]() |
Re: StreamWrite erzeugt nur 0 Byte-File
Also richtig will das noch nicht funktionieren. Mein bisheriger Code:
Delphi-Quellcode:
VAR DateiStream : TStream;
lBytesToRead, lReadCount : Int64; ReadMuster : STRING[64]; CONST TestMuster = '#abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+'; BEGIN TRY TRY DateiStream:=TFileStream.Create(LW+':\'+Datei, fmOpenRead); IF DateiStream.Size MOD Length(TestMuster) <> 0 THEN Result:=False ELSE BEGIN lBytesToRead:=SizeInMByte * 1024 * 1024; WHILE (lBytesToRead) > 0 DO BEGIN lReadCount:=Min(lBytesToRead, Length(TestMuster)); SetLength(ReadMuster, 64); ReadMuster:=''; DateiStream.ReadBuffer(ReadMuster, lReadCount); IF ReadMuster<> TestMuster THEN Result:=False; Dec(lBytesToRead, lReadCount); Application.ProcessMessages; END; END; FINALLY DateiStream.Free; END; EXCEPT Result:=False; END; END; |
Re: StreamWrite erzeugt nur 0 Byte-File
Du lässt dir auch deinen Stack überschreiben. Es wurde zuvor explizit das erste Zeichen bei Strings angegeben - aus gutem Grund. Du machst dies nicht und übergibst damit die Adresse der Stringvariablen auf deinem Stack und lässt dir diesen mit den Dateidaten vollkippen.
Und nochwas: Wenn du den String auf eine Länge bzw. Grösse von 64 Bytes setzt um ihn dann wieder auf eine Länge von 0 (Leerstring) zurück zu setzen, macht irgendwie, wenn man dies so liest in diesem Satz, wenig Sinn. Weil im Endeffekt hast du dann wieder 0 Bytes für deine Dateidaten. BTW: Schonmal aufgefallen, dass deine Funktion niemals True zurück gibt und du eigentlich sogar einen Hinweis von dem Compiler bekommst, dass der Rückgabewert der Funktion undefiniert sein könnte? |
Re: StreamWrite erzeugt nur 0 Byte-File
Zitat:
Wenn ich die brisante Zeile entferne, in welcher der String wieder auf '' gesetzt wird, dann wird tatsächlich etwas ausgelesen. Allerdings nur ca. 35 Zeichen von 64 Zeichen, obwohl lReadCount mit der Min-Berechnung auf 64 Byte festgelegt wird. Zitat:
|
Re: StreamWrite erzeugt nur 0 Byte-File
Zitat:
Schonmal mit der Angabe des erstens Zeichens probiert? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:02 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