2011-04-14 60 views
2

我的應用程序讀取和寫入大量的大中型文件。我想以壓縮格式存儲這些文件。節省磁盤空間和網絡時間。如何在不創建其他進程的情況下訪問gzip文件?

一種方式做到這一點是這樣的:

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

然後我就可以簡單地通過交換調用打開改變我現有的代碼。

從函數中可以明顯看出,我也想過使用zlib/compress庫。問題是結果不能作爲文件指針傳遞。

有沒有辦法做到這一點,不涉及創建一堆額外的進程?

+0

額外的過程是有用的。如果你的perl進程做了很多工作,並且你有多個處理器,你可以通過一個專用於zip/unzip的獨立進程(在1個CPU上),然後在perl上專門執行一個完整進程(在第二個CPU上)來獲得更好的性能。程序。 – bot403 2011-04-14 18:16:58

+2

電腦的**工作**是爲您運行流程。避開他們。 – tchrist 2011-04-14 18:20:19

回答

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>) {...} 
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"; 
相關問題