0

我想从大型(3+ GB,gzipped)FTP 下载中提取一些数据,并即时执行此操作,以避免转储然后完全下载到我的磁盘上。

要提取所需的数据,我需要逐行检查未压缩的流。

所以我正在寻找道德等价物

use PerlIO::gzip;

my $handle = open '<:gzip', 'ftp://ftp.foobar.com/path/to/blotto.txt.gz'
             or die $!;
for my $line (<$handle>) {
    # etc.
}
close($handle);

FWIW:我知道如何打开一个读取句柄ftp://ftp.foobar.com/path/to/blotto.txt.gz(with Net::FTP::repr),但我还没有弄清楚如何向:gzip这个打开的句柄添加一个层


我花了比找到上述问题答案的时间更长的时间,所以我想我会把它发布给下一个需要它的人。

4

2 回答 2

1

下面的代码来自IO::Compress FAQ

use Net::FTP;
use IO::Uncompress::Gunzip qw(:all);

my $ftp = new Net::FTP ...

my $retr_fh = $ftp->retr($compressed_filename);
gunzip $retr_fh => $outFilename, AutoClose => 1
    or die "Cannot uncompress '$compressed_file': $GunzipError\n";

要逐行获取数据,请将其更改为

use Net::FTP;
use IO::Uncompress::Gunzip qw(:all);

my $ftp = new Net::FTP ...

my $retr_fh = $ftp->retr($compressed_filename);
my $gunzip = new IO::Uncompress::Gunzip $retr_fh, AutoClose => 1
    or die "Cannot uncompress '$compressed_file': $GunzipError\n";

while(<$gunzip>)
{
    ...
}
于 2014-04-19T14:56:10.047 回答
1

好的,答案是(IMO)一点也不明显binmode($handle, ':gzip')

这是一个充实的例子:

use strict;
use Net::FTP;
use PerlIO::gzip;

my $ftp = Net::FTP->new('ftp.foobar.com') or die $@;
$ftp->login or die $ftp->message;  # anonymous FTP
my $handle = $ftp->retr('/path/to/blotto.txt.gz') or die $ftp->message;

binmode($handle, ':gzip');

for my $line (<$handle>) {
    # etc.
}
close($handle);
于 2014-04-19T13:28:22.290 回答