2012-12-06 11 views
8

Im przy użyciu LWP do pobrania typu pliku wykonywalnego i odpowiedzi w pamięci, jestem w stanie hash pliku. Jak jednak zapisać ten plik w moim systemie? Myślę, że jestem na niewłaściwym torze z tym, co próbuję poniżej. Pobieranie przebiega pomyślnie, ponieważ mogę poprawnie wygenerować hasz (dwukrotnie sprawdziłem, pobierając rzeczywisty plik i porównując skróty).perl zapisać plik pobrany przez 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; 

Jeśli zastanawiasz się, dlaczego nie ja zamiast pobrać wszystko następnie zanalizować folder dla każdego pliku i haszyszu, jego ponieważ im pobieranie wszystkie te pliki w pętli. I podczas każdej pętli wysyłam odpowiedni URL źródłowy (gdzie ten plik został znaleziony) wraz z nazwą pliku i hash do bazy danych za jednym razem.

Odpowiedz

9

Spróbuj getstore() z 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

Wielkie dzięki, ale wadą getstore() jest to, że folder musi już istnieć. Przez chwilę byłem zszokowany, gdy nie pojawił się żaden plik/folder. –

1

getstore to doskonałe rozwiązanie, jednak dla nikogo innego przeczytaniu tej odpowiedzi w nieco innej konfiguracji, nie może rozwiązać ten problem.

Po pierwsze, być może cierpisz na problemy z tekstem binarnym.

bym zmienić

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

do

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; 

Powodem Lubię to lepsze jest to, że jeśli masz ustawione lub nabyte pewne ustawienia w przeglądarce obiektu ($ UA), są ignorowane w LWP :: Simple's getstore, ponieważ używa własnej przeglądarki.

Używa również otwartej wersji z trzema parametrami, która powinna być bezpieczniejsza.

Innym rozwiązaniem byłoby użycie metody wywołania zwrotnego i zapisanie pliku podczas pobierania, jeśli na przykład mamy do czynienia z dużym plikiem. Algorytm mieszania musiałby zostać zmieniony tak, to chyba nie ma znaczenia tutaj, ale tutaj jest próbka:

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; 

A jeśli rozmiar nie ma znaczenia (i mieszania odbywa się w inny sposób) można po prostu zapytać w przeglądarce zapisz go bezpośrednio:

my $req = HTTP::Request->new(GET => $uri); 
$res = $ua->request($req, $filename); 
Powiązane problemy