Perl:如何在循环中下载大型zip文件并提供反馈

时间:2015-12-07 17:18:55

标签: perl

使用Perl,如何从Web服务器下载大型zip文件,在下载时,发布状态消息?我尝试LWP::Simplegetstore()并启用$ua->show_progress(1),但在下载时它会挂起,我无法通过POSIX命名管道向其他应用程序提供反馈。

2 个答案:

答案 0 :(得分:1)

对此答案的评论后,您可以在下面尝试更准确地指出问题。这会使子项下载,并且在主服务器中,您将能够从文件描述符中读取进度信息。

然而,下载和处理进度的程序之间的更好的交互可能是可能的,因为在我看来,只是为了使下载以某种方式显示的过程是丑陋的。但是下载反馈的这部分主要取决于您设计应用程序的进度的方式,而且这个设计也是未知的。

use strict;
use warnings;
use LWP::UserAgent;

my $url = "http://...";
my $file = "outputfile";

pipe my $rfh, my $wfh;
defined( my $pid = fork() ) or die "fork failed: $!";
if ($pid == 0) {
    # download in child, redirect progress to pipe
    close($rfh);
    $wfh->autoflush(1);
    open(STDERR,">&",$wfh) || die $!;
    close($wfh);

    my $ua = LWP::UserAgent->new;
    $ua->show_progress(1);
    $ua->get($url, ':content_file' => $file );
    exit;
}

# read in master from pipe
close($wfh);
$SIG{CHLD} = 'IGNORE';
while (sysread($rfh, my $buf, 8192,0)) {
    print "progress... $buf\n";
}

答案 1 :(得分:-1)

#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple qw($ua getstore);
use POSIX qw(WNOHANG);

my $sURL = "http://example.com/example.zip";
my $sSaveFile = "/tmp/download.zip";

# it's probably a good idea to first check the server with a HEAD request on the URL before wasting time on a download. 
# But, besides that, here you go...

my $sMessage = "Downloading";
my $pid = fork(); 
if ($pid == 0) {
  getstore($sURL,$sSaveFile);
  exit;
}
do {
    # here, I print, but you could also provide feedback via Named Pipes or some other mechanism
    # you might also want to do a byte check to see if the file size is increasing, and if not, increase a flag counter, and if you hit like 5 flags, give up on the download with a "last" statement.
    # remember, byte checks can easily be done with: my $nBytes = (-s $sSaveFile);
    print "$sMessage\n";
    $sMessage .= '.';
    sleep(2);
} while (waitpid($pid, WNOHANG)==0);
print "\n\nDONE\n\n";

我发现我必须这样做,而不是炮轰和运行curl,因为在OSX Lion上,它有一个错误,在30秒后用于管道进程时Curl超时,而之后的OSX版本不再有这个错误。