开发者

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";
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜