2012-12-06 139 views
8

使用LWP下载可执行文件类型和内存中的响应,我能够散列该文件。但是,我怎样才能保存这个文件在我的系统?我想我在下面试着走错了路。下载成功了,因为我能够正确生成哈希(我已经通过下载实际文件和比较哈希来进行双重检查)。perl保存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; 

如果你想知道为什么我不能代替下载的一切,然后分析该文件夹的每个文件的哈希,其由于IM下载在一个循环中的所有这些文件。在每个循环中,我都会将相关源URL(发现此文件的位置)以及文件名和散列一起上传到数据库中。

回答

9

尝试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); 
+0

非常感谢,但getstore()的缺点是该文件夹必须已经存在。当没有文件/文件夹出现时,我感到震惊。 –

1

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);