AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

StreamWrite erzeugt nur 0 Byte-File

Ein Thema von little_budda · begonnen am 5. Jun 2008 · letzter Beitrag vom 18. Jun 2008
Antwort Antwort
Seite 3 von 4     123 4      
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#21

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 10:49
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:
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;
Deshalb empfehle ich WriteBuffer anstelle von Write zu verwenden.
Andreas
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#22

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 10:53
Nun gut, dann umgestellt um die Exception von WriteBuffer() zu nutzen...

Delphi-Quellcode:
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;
Ja, wieder im Beitragseditor geschrieben und ungetestet. Also keine Schläge, wenn wieder Kleinigkeiten falsch sind...
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#23

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 10:54
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:

CONST TestMuster = '#abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+'; 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.
Devid
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#24

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 10:59
Der jetzige Code deckt alle Dateigrößen ab, auch ungerade

Delphi-Quellcode:
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;
Wieder ungetestet, aber sollte so klappen.
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#25

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 11:39
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:

lStream := TFileStream.Create(AFilename, fmOpenRead); und andererseits eine lokale Stringvariable namens ReadMuster deklariere sowie ReadBuffer einsetze:

Delphi-Quellcode:
CONST TestMuster = '#abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+';
VAR ReadMuster : STRING;
BEGIN
...
DateiStream.ReadBuffer(ReadMuster, lReadCount);
IF ReadMuster <> TestMuster THEN ShowMessage('Gelesenes Muster stimmt nicht mit dem Testmuster überein.');
...
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 ?
Devid
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#26

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 12:38
Der String ist leer. Setze die entsprechende Stringlänge bevor du was einliest. Delphi-Referenz durchsuchenSetLength
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#27

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 14:25
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;
Devid
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#28

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 14:59
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?
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#29

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 15:11
Zitat von Muetze1:
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.
In der Hilfe wird der Rückgabepuffer mit "var Buffer;" deklariert, woraus ich schließe, dass es sich auch um einen String handeln kann. Ich hatte davor mit BlockRead gearbeitet und konnte eben genau 64 Byte einlesen. Hier scheint das komplizierter zu sein.

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 von Muetze1:
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?
Ja, vor dem ersten Try-Wort wird Result:=True gesetzt. Das ist hier irgendwie untergegangen.
Devid
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#30

Re: StreamWrite erzeugt nur 0 Byte-File

  Alt 17. Jun 2008, 15:14
Zitat von devidespe:
In der Hilfe wird der Rückgabepuffer mit "var Buffer;" deklariert, woraus ich schließe, dass es sich auch um einen String handeln kann. Ich hatte davor mit BlockRead gearbeitet und konnte eben genau 64 Byte einlesen. Hier scheint das komplizierter zu sein.
Achtung! Das ist ein typenloser Parameter und die Strings sind mit Referenzzählung versehen. Diese Analogie kann man nicht so einfach schliessen.

Schonmal mit der Angabe des erstens Zeichens probiert?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


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 01:17 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