Board logo

标题: [转载代码] [LWP::UserAgent]Perl下载文件的同时显示进度 [打印本页]

作者: 523066680    时间: 2014-9-15 21:21     标题: [LWP::UserAgent]Perl下载文件的同时显示进度

原帖 http://www.perlmonks.org/?node_id=702035
  1. #!/usr/bin/perl -w
  2. #http://www.perlmonks.org/?node_id=702035
  3. use strict;
  4. use LWP::UserAgent;
  5. # don't buffer the prints to make the status update
  6. $| = 1;
  7. my $ua = LWP::UserAgent->new();
  8. my $received_size = 0;
  9. my $url = 'http://search.cpan.org/CPAN/authors/id/C/CH/CHM/OpenGL-0.6703.tar.gz';
  10. print "Fetching $url\n";
  11. my $request_time = time;
  12. my $last_update = 0;
  13. my $response = $ua->get($url,
  14.                         ':content_cb'     => \&callback,
  15.                         ':read_size_hint' => 8192,
  16.                        );
  17. print "\n";
  18. sub callback {
  19.   my ($data, $response, $protocol) = @_;
  20.   my $total_size = $response->header('Content-Length') || 0;
  21.   $received_size += length $data;
  22.   # write the $data to a filehandle or whatever should happen
  23.   # with it here. Otherwise the data isn't saved
  24.   my $time_now = time;
  25.   # this to make the status only update once per second.
  26.   return unless $time_now > $last_update or $received_size == $total_size;
  27.   $last_update = $time_now;
  28.   print "\rReceived $received_size bytes";
  29.   printf " (%i%%)", (100/$total_size)*$received_size if $total_size;
  30.   printf " %6.1f/bps", $received_size/(($time_now-$request_time)||1)
  31.      if $received_size;
  32. }
复制代码
我也是最近才接触一下LWP::UserAgent
以上代码只管下载指定大小的信息到 $date 中,并不保存文件。注意帮助中提到的:

            :content_file   => $filename
            :content_cb     => \&callback
            :read_size_hint => $bytes

        If a $filename is provided with the ":content_file" option, then the
        response content will be saved here instead of in the response
        object. If a callback is provided with the ":content_cb" option then
        this function will be called for each chunk of the response content
        as it is received from the server. If neither of these options are
        given, then the response content will accumulate in the response
        object itself. This might not be suitable for very large response
        bodies. Only one of ":content_file" or ":content_cb" can be
        specified.
The content of unsuccessful responses will always
        accumulate in the response object itself, regardless of the
        ":content_file" or ":content_cb" options passed in.


设置 "保存文件" 和 设置 "回调函数",只能选其一。不过当我们设置回调函数的时候,该函数默认传入3个参数:

        The callback function is called with 3 arguments: a chunk of data, a
        reference to the response object
, and a reference to the protocol
        object
. The callback can abort the request by invoking die(). The
        exception message will show up as the "X-Died" header field in the
        response returned by the get() function.

分别是  $data, $response, $protocol , 其中下载的数据块就保存在$data中,其他两个不认识
所以如果要在这个示例代码中保存下载的数据,可以公开声明一个文件句柄,然后在callback函数
中将$data写入文件即可。




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2