2012-12-06 91 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);