Announcement

Collapse
No announcement yet.

ZLib mit IB-Datenfeld

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • ZLib mit IB-Datenfeld

    Hallo,

    ich habe ein Problem mit der ZLib-Komponente. Das Komprimieren klappt anstandslos, aber mit dem Dekomprimieren gibt es ein großes Problem. Beim Lesen aus dem dekomprimierten Stream (ZStream) (Feld aus IB-Datenbank) mit der festen Buffer-Größe 4096 wird als Ergebnis aus dem Read-Aufruf (<B>Count := ZStream.Read(ZLibBuffer, ZLibBufferSize)</B>) immer die ZLibBufferSize zurückgegeben.

    Auch wenn die Daten vollständig dekomprimiert worden sind (die Datei ist korrekt auf der Festplatte und auch lesbar), bricht die Schleife nicht ab.

    Was soll ich machen? Hat jemand eine Idee? Ist vielleicht irgendwas mit dem BlobStream falsch? Ich benutze D5Pro UpdatePack 1 deutsch, IB 5, Win2000 Prof..

    Lars

    Hier kommt der Code-Ausschnitt:

    <pre>
    implementation

    const
    ZLibBufferSize = 4096;

    var
    ZLibBuffer: array[0..ZLibBufferSize - 1] of Byte;

    procedure LoadPicture(ID: Integer; var Pic: TPicture);
    var
    InFile : TStream;
    OutFile : TStream;
    TextStream : TMemoryStream;
    ZStream : TCustomZLibStream;
    Count : Integer;
    Reading : Boolean;

    begin
    with DM.qryTemp do begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT ' + fldPicMainPic + ' FROM ' + tblPic);
    SQL.Add('WHERE ' + fldPicPicID + '=' + IntToStr(ID));
    Open;
    InFile := CreateBlobStream(FieldByName(fldPicMainPic), bmRead);
    end;//with

    if InFile.Size = 0 then begin
    InFile.Free;
    ShowMessage('Keine Bilddaten in der Datenbank vorhanden');
    Exit;
    end;
    try
    OutFile := TFileStream.Create('bild' + IntToStr(ID), fmCreate or fmOpenWrite);
    // OutFile := TMemoryStream.Create;
    try
    ZStream := TDecompressionStream.Create(InFile);
    try
    Reading := True;
    while Reading do begin
    Count := ZStream.Read(ZLibBuffer, ZLibBufferSize);
    if Count <> 0 then
    OutFile.WriteBuffer(ZLibBuffer, Count)
    else
    Reading := False;
    end;//while
    finally
    ZStream.Free;
    end;
    // Pic.Bitmap.LoadFromStream(OutFile);
    finally
    OutFile.Free;
    end;
    finally
    InFile.Free;
    end;
    end;
    </pre>

  • #2
    Hallo,

    im Beispielprojekt SrcArc aus meinem Buch <b>Client/Server Datenbankentwicklung mit Delphi</b> greife ich auch auf ZLib zurück, um komprimierte Dateien aus einer InterBase-Datenbank auszulesen und als Datei in unkomprimierter Form abzuspeichern. Das sieht bei mir folgendermassen aus:
    <pre>
    procedure TDM.ExportProjectFiles(ExportPath: String);
    resourcestring
    cErrNoPath = 'Der Exportpfad "%s" ist ungültig';
    cErrNoData = 'TBlobStream enthält keine Daten!';
    var
    sExportName : String;
    Count : Integer;
    InFile : TBlobStream;
    OutFile : TStream;
    ZStream : TCustomZLibStream;
    begin
    // Zielverzeichnis gültig?
    if Length(ExportPath) = 0
    then raise Exception.CreateFmt(cErrNoPath, [ExportPath]);
    // alle Projektdateien auslagern
    with QueryExportFiles do
    begin
    try
    // Projektnummer als Parameter übergeben
    Params[0].Value := TableProVerVERNR.Value;
    Open;
    with FormExport.ProgressBar1 do
    begin
    Max := RecordCount;
    Step := 1;
    end;
    //ShowMessage(IntToStr(RecordCount));
    while not EOF do
    begin
    sExportName := ExportPath + QueryExportFilesFILENAME.Value;
    // ZLib
    InFile := TBlobStream.Create(QueryExportFilesFILEDATA,bmRead );
    // wurden Daten aus dem Blob-Feld gelesen ?
    if InFile.Size = 0 then
    begin
    InFile.Free;
    ShowMessage(cErrNoData);
    Exit;
    end;
    try
    // Exportdatei anlegen (Exportpfad + Dateiname)
    OutFile := TFileStream.Create(sExportName, fmCreate or fmOpenWrite);
    try
    // komprimierte Blob-Daten entkomprimieren
    ZStream := TDecompressionStream.Create(InFile);
    try
    // in 4096-Byte Häppchen in die Datei schreiben
    while True do
    begin
    Count := ZStream.Read(ZLibBuffer, ZLibBufferSize);
    if Count <> 0
    then OutFile.WriteBuffer(ZLibBuffer,Count)
    else Break;
    end;
    finally
    // Free -> Buffer wird geleert
    ZStream.Free;
    end;
    finally
    OutFile.Free;
    end;
    finally
    InFile.Free;
    end;
    FormExport.ProgressBar1.StepIt;
    Next;
    end;
    finally
    Close;
    FormExport.ProgressBar1.Position := 0;
    end;
    end;
    // Feld ABSCHLUSS in ProVer aktualisieren
    with SP_ProVerExport do
    begin
    Params[0].Value := TableProVerVERNR.Value;
    Execproc;
    end;
    // Anzeige aktualisieren
    TableProVer.Refresh;
    end;
    </pre>
    &#10

    Comment


    • #3
      Hallo Andreas,

      danke für Deinen Tipp, aber mein Code-Fragment macht eigentlich genau das gleiche wie Deines (ich habe es übrigens nach Deinem Hinweis auch in Deinem Buch gefunden). Deine Lösung funktioniert aber ebensowenig.

      Ich habe herausgefunden, dass es ein Bug in ZLib.pas ist, den man leicht beheben kann und der erst ab ZLib.pas von Delphi 5 (nicht bei Delphi 4) auftritt. Hier ein Auszug aus der Newsgroup:

      <b>
      This is a bug in ZLib, I have already submitted it (#433728) here:
      > http://pso.inprise.com/webcustomer/clearexx_cgi/x_Case_Bug.htm?case.id_number=433728&case.cclist2= JohannesBerg
      (URL may wrap)
      you can find a fix there as well (by Finn Tolderlund)
      </b>

      Grüße

      Lar

      Comment


      • #4
        Hallo,

        das Beispielprojekt auf der CDROM zum Buch sollte in jedem Fall funktionieren, denn dort liegen die "alten" ZLIB-Units mit im Programmverzeichnis ;-

        Comment


        • #5
          Hi,<br>
          können mir ZLIB gepackete Dateien auch under Unix entpackte werden??
          <br>
          Helmu

          Comment

          Working...
          X