10

我使用 LWP 下载可执行文件类型并在内存中响应,我能够散列文件。但是,如何将这个文件保存在我的系统上?我认为我在下面的尝试中走错了路。下载成功,因为我能够正确生成哈希(我通过下载实际文件并比较哈希进行了仔细检查)。

use strict;
use warnings;
use LWP::Useragent;
use Digest::MD5    qw( md5_hex );
use Digest::MD5::File qw( file_md5_hex );
use File::Fetch;

my $url = 'http://www.karenware.com/progs/pthasher-setup.exe';
my $filename = $url;
$filename =~ m/.*\/(.*)$/;
$filename = $1;
my $dir ='/download/two';
print "$filename\n";

my $ua = LWP::UserAgent->new();
my $response = $ua->get($url);
die $response->status_line if !$response->is_success;
my $file = $response->decoded_content( charset => 'none' );
my $md5_hex = md5_hex($file);
print "$md5_hex\n";
my $save = "Downloaded/$filename";
    unless(open SAVE, '>>'.$save) {
        die "\nCannot create save file '$save'\n";
    }
    print SAVE $file;
    close SAVE;

如果您想知道为什么我不下载所有内容然后解析每个文件和哈希的文件夹,这是因为我在循环中下载所有这些文件。在每个循环中,我将相关的源 URL(找到该文件的位置)连同文件名和哈希一起上传到数据库中。

4

2 回答 2

10

尝试getstore()LWP::Simple

use strict;
use warnings;
use LWP::Simple qw(getstore);
use LWP::UserAgent;
use Digest::MD5    qw( md5_hex );
use Digest::MD5::File qw( file_md5_hex );
use File::Fetch;

my $url = 'http://www.karenware.com/progs/pthasher-setup.exe';
my $filename = $url;
$filename =~ m/.*\/(.*)$/;
$filename = $1;
my $dir ='/download/two';
print "$filename\n";

my $ua = LWP::UserAgent->new();
my $response = $ua->get($url);
die $response->status_line if !$response->is_success;
my $file = $response->decoded_content( charset => 'none' );
my $md5_hex = md5_hex($file);
print "$md5_hex\n";
my $save = "Downloaded/$filename";
getstore($url,$save);
于 2012-12-06T09:49:35.937 回答
5

getstore 是一个很好的解决方案,但是对于其他在稍微不同的设置中阅读此响应的人来说,它可能无法解决问题。

首先,您很可能只是遇到了二进制/文本问题。

我会改变

my $save = "Downloaded/$filename";
unless(open SAVE, '>>'.$save) {
    die "\nCannot create save file '$save'\n";
}
print SAVE $file;
close SAVE;

my $save = "Downloaded/$filename";
open my $fh, '>>', $save or die "\nCannot create save file '$save' because $!\n";
# on platforms where this matters
# (like Windows) this is needed for 
# 'binary' files:
binmode $fh;
print $fh $file;
close $fh;

我更喜欢这个的原因是,如果您在浏览器对象 ($ua) 上设置或获取了一些设置,它们会在 LWP::Simple 的 getstore 中被忽略,因为它使用自己的浏览器。

此外,它使用了 open 的三参数版本,应该更安全。

另一种解决方案是在下载文件时使用回调方法并存储文件,例如,如果您正在处理一个大文件。必须更改散列算法,因此这里可能不相关,但这里有一个示例:

my $req = HTTP::Request->new(GET => $uri);
open(my $fh, '>', $filename) or die "Could not write to '$filename': $!";
binmode $fh;
$res = $ua->request($req, sub {
    my ($data, $response, $protocol) = @_;
    print $fh $data;
});
close $fh;

如果大小不重要(并且散列是通过其他方式完成的),您可以让您的浏览器直接存储它:

my $req = HTTP::Request->new(GET => $uri);
$res = $ua->request($req, $filename);
于 2014-12-06T21:48:12.980 回答