如何在不创建其他进程的情况下访问gzipped文件?

3

我的应用程序需要读写大量中等到大型文件。我希望将它们存储为压缩格式。这样可以节省磁盘空间和网络时间。

一种实现方法是使用以下方式:

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;
  }
}

我可以通过交换open函数的调用来简单地更改我的现有代码。

从这个函数中可以看出,我也考虑过使用zlib/compress库。问题是结果不能像文件指针一样传递。

有没有一种方法可以做到这一点,而不需要创建大量额外的进程?


额外的进程可能是有用的。如果你的 Perl 进程执行了大量的工作,并且你有多个处理器,那么通过将一个专门用于 zip/unzip 的单独进程(在第一个 CPU 上)和一个专门用于 Perl 程序的整个进程(在第二个 CPU 上)可以获得更好的性能。 - bot403
2
计算机的工作是为您运行进程。不要回避它们。 - tchrist
3个回答

12

来自IO::Uncompress::Gunzip的文档。

use IO::Uncompress::Gunzip qw($GunzipError);

my $z = IO::Uncompress::Gunzip->new( $input )
    or die "IO::Uncompress::Gunzip failed: $GunzipError\n";
变量 $z 现在是一个文件句柄,您可以像往常一样使用它。
while (<$z>) {...}

1

0

请查看您的 Perl 版本中的 IO::* 命名空间。

例如 Debian old-stable (5 - Lenny) 的 Perl 和下一个版本,提供 IO::Uncompress::GunzipIO::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";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接