我使用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(找到此文件的位置)以及文件名和散列一次性上传到数据库中。
答案 0 :(得分: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);
答案 1 :(得分:3)
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);