Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here


How To

How can I zip content using a stream? by Griffyn
Posted: 16 Sep 07 (Edited 20 Sep 07)

I'm surprised how often I've wanted to be able to do this in different situations: I have data in memory that I want to compress and send via e-mail or via TCP.  Using the freeware Abbrevia compression toolkit (http://sourceforge.net/projects/tpabbrevia/), this can be accomplished by
  • creating a TAbZipper object
  • either writing to it via a TStream, or saving the data I have to disk
  • adding the file to the TAbZipper object
  • Opening the zipfile from the disk and attach to the e-mail, or send via TCP using a TFileStream
Sure, that works... but it's a tad inefficient.  Why is the filesystem getting involved at all?  Unfortunately, the Abbrevia toolkit doesn't seem to offer a way to work only with TMemoryStream objects.  But I found a way.  First up, create yourself a descendant of TABZipArchive:


  AbZipTyp, AbArcTyp, AbZipPrc;

  TZipStream = class(TAbZipArchive)
    procedure ZipHelper(Sender : TObject; Item : TAbArchiveItem; OutStream : TStream);
    procedure ZipHelperStream(Sender : TObject; Item : TAbArchiveItem; OutStream, InStream : TStream);
    constructor CreateFromStream( aStream : TStream; const ArchiveName : string ); override;

{ TZipStream }

constructor TZipStream.CreateFromStream(aStream: TStream;
  const ArchiveName: string);
  DeflationOption := doMaximum;
  CompressionMethodToUse := smDeflated;
  InsertHelper := ZipHelper;
  InsertFromStreamHelper := ZipHelperStream;

procedure TZipStream.ZipHelper(Sender: TObject; Item: TAbArchiveItem; OutStream: TStream);
  AbZip(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);

procedure TZipStream.ZipHelperStream(Sender: TObject; Item: TAbArchiveItem; OutStream, InStream: TStream);
  if Assigned(InStream) then
    AbZipFromStream(TAbZipArchive(Sender), TAbZipItem(Item), OutStream, InStream);

And then use it like this.  This example adds data from a TStringStream to an e-mail message as a zip attachment:


procedure EmailStrings;
  m : TIdMessage;   // Indy e-mail message object
  ss : TStringStream;    // to hold data we're going to zip
  ms : TMemoryStream;    // temporary stream
  z : TZipStream;     // our zip object
  m := TIdMessage.Create;
    { TODO: populate TIdMessage with From, Subject, etc. }
    ss := TStringStream.Create('');
      { TODO: populate the TStringStream object with data }
      ss.Position := 0;     // must reposition at beginning of stream
      ms := TMemoryStream.Create;    // temporary memory stream
        z := TZipStream.CreateFromStream(ms, '');
          z.AddFromStream('filename.txt', ss);   // filename within zip file
          z.FStream.Position := 0;
          with TIdAttachmentMemory.Create(m.MessageParts, z.FStream) do
            Filename := 'filename.zip';   // filename of attachment in e-mail
    { TODO: send message }

Back to Embarcadero: Delphi FAQ Index
Back to Embarcadero: Delphi Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close