Integrate Compress::Zlib seamlessly w/no compression?

  • Thread starter peter.j.torelli
  • Start date
P

peter.j.torelli

Hello,

I use Compress::Zlib extensively for reading files, but I always run
into this problem when writing:

If the user does not want to write compressed output, I can't use
Compress::Zlib for writing. I tried all the Zlib options to turn off
compression, and it always inserts a binary header, even with no
compression.

Since the read/write/close methods for the object are not the same as
an uncompressed filehandle, I can't just use a different open method
for the same variable. Instead I end up having to use open() and a
pipe to gzip if compression is desired so that the same filehandle can
be used without a ton of conditionals in the code.

So the simple question is: how do I turn off all compression and
headers when I use gzopen() and just write a plain text file?

(Note: I already played with Compress::Zlib::Z_NO_COMPRESSION, and
-WindowBits=>-MAX_WBITS, as well as "w" vs. "wb".)

Thanks,
Peter
 
B

Brian McCauley

A. Sinan Unur said:
(e-mail address removed) wrote in @d34g2000cwd.googlegroups.com:


But, that is the wrong question to ask. You can just write two dispatcher
class that have the identical interface, and hide the different
implementations of read/write/close methods behind these objects'
interfaces.

Or write a very thin shim that presents an interface like
Compress::Zlib's read/write/close but just passes them strait through
and use one of these objects instead.

Of course you could just us IO::Zib which gives Compress::Zlib a more
filehandle-like interface.

There's also PerlIO::gzip but I don't know if this uses zlib or an
external gzip process.
 
P

Paul Marquess

There is no way to suppress the gzip header with the gzopen interface, even
when you use Z_NO_COMPRESSION.
Or write a very thin shim that presents an interface like
Compress::Zlib's read/write/close but just passes them strait through
and use one of these objects instead.

Of course you could just us IO::Zib which gives Compress::Zlib a more
filehandle-like interface.

There's also PerlIO::gzip but I don't know if this uses zlib or an
external gzip process.

IO::Zlib or PerlIO::gzip are the best approaches to use at the moment.

if (want compressed file) {
$fh = IO::Zlib->new($filename, "wb9");
}
else {
$fh = open ">$filename";
}

die "error ... error"
unless $fh;

If you want to get into manipulating the gzip header, you could use
IO::Compress::Gzip, but that's still beta code.

Paul
 
P

peter.j.torelli

Paul,

I really like your solution, it is very clean and fits with my style.
Thank you.

The idea of writing another abstraction layer to handle this simple
case (IMHO) is preposterous as I would have to tote this baggage around
indefinitely. This sol'n adds a few extra lines of code, but that's
way cleaner than supporting another object.

--Peter
 
P

peter.j.torelli

I understand that it is a small amount of code, and amortized over many
calls using the conditional becomes even more cost-effective in terms
of typing. However in the environment I work in, the cost of managing
another module adds to the complexity of our release environment. And
since I'll only be calling it a few times in each monolithic perl
script (that's how we write; i know, i know...), the conditional suits
my needs. I should have defined "preposterous" to mean "preposterous
in MY particular environment".

Thanks, Sinan.

--P

A. Sinan Unur said:
(e-mail address removed) wrote in

[ Please do not top-post ]
...

I really like your solution, it is very clean and fits with my style.
Thank you.

The idea of writing another abstraction layer to handle this simple
case (IMHO) is preposterous

Hmmm ...

#!/usr/bin/perl

package My::Open;

use strict;
use warnings;

sub open {
my ($fn, $mode, $compress) = @_;

if ( $compress ) {
require IO::Zlib;
return IO::Zlib->new($fn, $mode) if $compress;
}
else {
open my ($fh), $mode, $fn;
return $fh;
}
}

package main;

my $fh1 = My::Open::eek:pen('test1.gz', 'wb', 1)
or die $!;

print $fh1 "This is a test\n" or die $!;

close $fh1 or die $!;

my $fh2 = My::Open::eek:pen('test2.txt', '>')
or die $!;

print $fh2 "This is a test\n" or die $!;

close $fh2 or die $!;

__END__

It all depends on how many times you need to write that conditional, or
if other programs could use such functionality.

--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top