使用Perl,如何从Web服务器下载大型zip文件,在下载时,发布状态消息?我尝试LWP::Simple的getstore()
并启用$ua->show_progress(1)
,但在下载时它会挂起,我无法通过POSIX命名管道向其他应用程序提供反馈。
答案 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版本不再有这个错误。