Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Binäre Ausgabe in Konsolenfenster (https://www.delphipraxis.net/3087-binaere-ausgabe-konsolenfenster.html)

Chewie 22. Feb 2003 12:45


Binäre Ausgabe in Konsolenfenster
 
Ich bin gerade dabei, mir ein CGI-Programm für den Apache zu bauen, das SVG-Daten automatisch komprimiert, sprich in SVGZ-Daten umwandelt. Mein Programm öffnet dazu die Datei, die der Apache übertragen will, komprimiert den Inhalt und speichert die komprimierte Datei in einem MemoryStream. Eingabe und Verarbeitung funktioniert, damit die gute Eva aber glücklich ist, fehlt natürlich noch die Ausgabe. Und an der haperts.
Da die komprimierten Daten binär sind, kann ich zum Lesen aus dem Memory-Stream keine Strings benutzen. Also habe ich es mit einem Array of Byte versucht, das den Inhalt des Streams einliest und dann in die Standard-Ausgabe schreibt. Codemäßig sieht das so aus:

Delphi-Quellcode:
var
  InputStream: TFileStream;
  OutputStream: TMemoryStream;
  CompressionStream: ZLib.TCompressionStream;
  buf: Array of Byte;
  a: Integer;
  SVGPath: String;

begin
  WriteLn('Content-type: image/xml-svg');
  WriteLn;
  SVGPath := GetEnvVar('PATH_TRANSLATED');  //Dateiname als Apache-Umgebungsvariable
  InputStream:=TFileStream.Create(SVGPath, fmOpenRead);
  OutputStream:=TMemoryStream.Create;
  CompressionStream:=TCompressionStream.Create(clMax, OutputStream);
  CompressionStream.CopyFrom(InputStream, InputStream.Size);
  CompressionStream.Free;
  SetLength(buf,OutputStream.Size);
  OutputStream.Read(buf,OutputStream.Size);
  OutputStream.SaveToFile('c:/test.svgz'); //Datei, um erfolgreiche Komrprimierung zu bestätigen: erfolgreich
  for a := 0 to Length(buf) - 1 do write(char(buf[a])); //hier Ausgabe
  OutputStream.Free;
  InputStream.Free;
end.
Ausgegeben bekomme ich hier lauter #00. Kann mir einer sagen, warum??

Christian Seehase 22. Feb 2003 14:30

Moin Chewie,

wenn ich das richtig sehe, dann hat OutputStream die Grösse 0, denn er wird nur angelegt, aber nichts da reingeschrieben, somit wird die Länge von buf auf 0 gesetzt, und die Schleife läuft von 0 bis -1, wird also übersprungen.

Zitat:

Zitat von Chewie
Da die komprimierten Daten binär sind, kann ich zum Lesen aus dem Memory-Stream keine Strings benutzen.

doch:

Delphi-Quellcode:
var
  sBuf : string;
  msIN : TMemoryStream;

begin
  msIN := TMemoryStream.Create;
  try
    msIN.LoadFromFile('IrgendeineDatei');
    SetLength(sBuf,msIN.Size);
    msIN.Read(sBuf[1],length(sBuf));
  finally
    FreeAndNil(msIN);
  end;
end;

Chewie 22. Feb 2003 14:35

Zitat:

Zitat von Christian Seehase
Moin Chewie,

wenn ich das richtig sehe, dann hat OutputStream die Grösse 0, denn er wird nur angelegt, aber nichts da reingeschrieben, somit wird die Länge von buf auf 0 gesetzt, und die Schleife läuft von 0 bis -1, wird also übersprungen.

Nein, leider nicht. Bei TCompressionStream.Create wird OutputStream übergeben; in diesen wird laut den Kommentaren in der zlib.pas die komprimierten Daten kopiert. Und wenn ich OutputStream.SaveToFile ausführe, werden ja die Daten richtig gespeichert.
Nur das Lesen klappt nicht. buf ist voller Nullen. Auch wenn ich buf als String deklarier, macht es keinen Unterschied.

Christian Seehase 22. Feb 2003 14:39

Moin Chewie,

solange Du den Buffer nicht als String benutzt, also z.B. mit ShowMessage ausgeben willst, oder mit + sNochnString etwas anfügen willst spielen binäre Nullen im String aber keine Rolle, denn die Längenangabe wird von Nullen im String nicht berührt.

Chewie 22. Feb 2003 14:56

OK, warum es mit dem MemoryStream nicht funktiniert, versteh ich nicht, aber es klappt mit einem StringStream.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:50 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