How do I access gzipped files without creating additional processes?
My application reads and writes a lot of medium to large files. I would like to store these in zipped format. Saves diskspace and network time.
One way to do it is with this:
sub fopen {
my $mode = shift;
my $filename = shift;
if ($filename =~ /\.gz$/) {
if ($mode eq "<") {
open(my $fp, "-|", "/usr/bin/gzcat $filename");
#my $fp = gzopen($filename, "rb") ;
return $fp;
}
if ($mode eq ">") {
open(my $fp, "|-", "/usr/bin/gzip > $filename");
#my $fp = gzopen($filename, "wb") ;
return $fp;
}
} else {
open(my $fp, $mode, $filename);
return $fp;
}
}
I can then change my existing code 开发者_JS百科simply by swapping the calls to open.
As is apparent from the function, I've also thought of using the zlib/compress library. The problem is that the result can't be passed around as a file pointer.
Is there a way to do this that doesn't involved creating a bunch of extra processes?
From the documentation of IO::Uncompress::Gunzip
use IO::Uncompress::Gunzip qw($GunzipError);
my $z = IO::Uncompress::Gunzip->new( $input )
or die "IO::Uncompress::Gunzip failed: $GunzipError\n";
The variable $z
is now a file handle that you can use as usual.
while (<$z>) {...}
Just to add some information about previous answers, from an old bench I made, PerlIO::gzip is faster than IO::Uncompress::Gunzip.
Look at the IO::* namespace on your Perl version.
For example Debian old-stable (5 - Lenny) Perl and next versions, ships IO::Uncompress::Gunzip and IO::Uncompress::AnyUncompress.
#!/usr/bin/perl
use strict ;
use warnings ;
use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
my $input = "file1.txt.gz";
my $output = "file1.txt";
gunzip $input => $output
or die "gunzip failed: $GunzipError\n";
精彩评论