ZlR has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

I must admit i haven't searched much for an answer but the docs are not very clear, it's the end of the week and there is something i don't quite understand ...

Here's what i do :

$fu = "bla bla bla bla" ; $ba = compress ( $fu ) ; open FFF, ">ba.txt.Z" or die "$!" ; print FFF $ba; close (FFF) ;
This produces a file with binary data in it but it doesnt seem to be a valid .Z file (or .gz for that matter...). I doubt this is the way the compress method is suposed to be used ...

The doc says :
$dest = compress($source) ;
Compresses $source. If successful it returns the compressed data. Otherwise it returns undef.
The source buffer can either be a scalar or a scalar reference.

I also tried with binmode FFF , and still no luck .
I'm missing something about buffer and in memory so if someone could explain this to me , it'd be great !!

ZlR.

Replies are listed 'Best First'.
Re: Compress::Zlib : what to do with the "in memory" data ?
by spq (Friar) on Jan 07, 2005 at 17:31 UTC

    I use Compress::Zlib for a number of in-memeory (un)compressions. I don't have any examples on hand for generating a file (I store to a database), but I did do that in tests to be sure the compressed data in the db could alternately be SELECT'd to a file and uncompressed with gzip.

    my $zipped_raw = Compress::Zlib::memGzip($raw_genome); my $raw_genome = Compress::Zlib::memGunzip($zipped_raw);

    So if you wanted to compress in memory and save to file based on your example:

    $fu = "bla bla bla bla" ; $ba = Compress::Zlib::memGzip( $fu ) ; open FFF, ">ba.txt.gz" or die "$!" ; print FFF $ba; close (FFF) ;

    However Compress::Zlib has methods that handle reading and writing gzip files built in.

    $gz->gzwrite($buffer) ;

    Which you may want to look at first if that's all your after.

    HTH
      Thanks a lot for you answer, gzwrite is interesting :
      open FFF, "<fu.txt" or die "$!" ; binmode FFF ; $gz = gzopen("fu.txt.gz", "wb") or die "gzerror" ; while ($buffer = <FFF>) { $gz->gzwrite($buffer) } close FFF ; $gz -> gzclose ;
      The resulting file is a valid gz file.
      I have to point out that i'm under win32, hence the binmode (otherwise newlines are washed out when i uncompress the file).

      But, i have a problem here : what i need to obtain is a .Z file and not a .gz .
      This might not be mandatory, but the resulting file is sent to someone else and i'll have to check if his programs can deal with a .gz .

      Do you know if Compress::Zlib will allow me to create a .Z file ? For exemple with inflate / deflate ? Or is zlib for gz compression only ?

      Thanks a lot,

      ZlR .

        Compress::Zlib and the underlying zlib library do not read or write .Z files. These are the files from the compress program, compressed using the once-patented LZW algorithm. zlib only does deflate, the algorithm used in gzip and zip files.

        AFAIK, there are no Perl modules for reading or writing .Z files. One option would be to pipe through zcat or gzip, which can read .Z files.

        Why do you want to use .Z files? .gz has better compression and is probably more widely supported now.

Re: Compress::Zlib : what to do with the "in memory" data ?
by zentara (Cardinal) on Jan 08, 2005 at 12:47 UTC
    I believe you need to use the gzopen function, instead of open to put the right header and stuff needed to make it a .gz file.
    #!/usr/bin/perl use Compress::Zlib; use strict; # see also the source to Tie::Gzip which demonstrates # (un)gzip using Compress::Zlib if installed. foreach my $f ( grep { -f } @ARGV ) { my ( $buffer, $gz ); if ( $f =~ /gz$/ ) { ( my $rtf = $f ) =~ s/(.)gz$//; open OOT, ">$rtf" or die "$0:$rtf:$!"; binmode OOT; $gz = gzopen( $f, "rb" ) or die "$0:$gzerrno:$!"; print OOT $buffer while $gz->gzread($buffer) > 0; die "$f: $gzerrno:$!" if $gzerrno != Z_STREAM_END; $gz->gzclose(); close(OOT); } else { # gzip our file open COOT, "$f" or die "$0:$f:$!"; binmode COOT; $gz = gzopen( "$f.gz", "wb" ) or die "$0:$gzerrno:$!"; while (<COOT>) { $gz->gzwrite($_) or die "$f.gz,$gzerrno:$!"; } $gz->gzclose; } }

    I'm not really a human, but I play one on earth. flash japh