Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca c'est pas
un probleme. Mais peut-on le recuperer par tranche de 1MO par exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO de
façon à pouvoir reprendre le téléchargement sur plusieur jour si nécéssaire
ou alors faire en sorte de reprendre à l'endroit ou cela c'est arrêter.
Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca c'est pas
un probleme. Mais peut-on le recuperer par tranche de 1MO par exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO de
façon à pouvoir reprendre le téléchargement sur plusieur jour si nécéssaire
ou alors faire en sorte de reprendre à l'endroit ou cela c'est arrêter.
Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca c'est pas
un probleme. Mais peut-on le recuperer par tranche de 1MO par exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO de
façon à pouvoir reprendre le téléchargement sur plusieur jour si nécéssaire
ou alors faire en sorte de reprendre à l'endroit ou cela c'est arrêter.
Dans l'article ,
a dit...
Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca c'est
pas un probleme. Mais peut-on le recuperer par tranche de 1MO par
exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO
de façon à pouvoir reprendre le téléchargement sur plusieur jour si
nécéssaire ou alors faire en sorte de reprendre à l'endroit ou cela
c'est arrêter.
Ce n'est pas facile à faire.
Le module Net::FTP a bien une méthode
get( REMOTE_FILE [, LOCAL_FILE [, WHERE]])
qui permet de commencer le téléchargement à l'offset WHERE, mais rien
ne permet d'arrêter le transfert quand une certaine taille est
atteinte.
J'ai modifié la méthode get en une méthode get_part qui prend les
mêmes paramètres plus un : la taille du morceau de fichier que l'on
désire :
get_part( REMOTE_FILE, LOCAL_FILE, WHERE, SIZE )
ajoute à la fin du fichier LOCAL_FILE la partie de REMOTE_FILE qui
commence à l'offset WHERE et de taille SIZE. La méthode renvoie
l'offset du morceau suivant, si on veut continuer (ou undef en cas
d'erreur). Quand l'offset est supérieur ou égal à la taille du
fichier, tout le fichier est chargé. Le tranfert est toujours en mode
binary pour éviter les problèmes de CR/LF.
Le petit script suivant teste la fonction en comparant les fichiers
obtenus par get et get_part.
HTH
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
#====== Ajout d'une méthode get_part à Net::FTP
package Net::FTP;
sub get_part {
my ( $ftp, $remote, $local, $where, $part_size ) = @_;
my ( $loc, $len, $buf, $resp, $data );
local *FD;
my $localfd = ref($local) || ref( $local ) eq "GLOB";
( $local = $remote ) =~ s#^.*/## unless ( defined $local );
croak("Bad remote filename '$remote'n") if $remote =~ /[rn]/s;
$ftp->binary;
${*$ftp}{'net_ftp_rest'} = $where if defined $where;
my $rest = ${*$ftp}{'net_ftp_rest'};
delete ${*$ftp}{'net_ftp_port'};
delete ${*$ftp}{'net_ftp_pasv'};
$data = $ftp->retr($remote) or return undef;
if ($localfd) {
$loc = $local;
}
else {
$loc = *FD;
unless ( sysopen( $loc,
$local,
O_CREAT
| O_WRONLY
| ( $rest ? O_APPEND: O_TRUNC )) ) {
carp "Cannot open Local file $local: $!n";
$data->abort;
return undef;
}
}
if ( $ftp->type eq 'I' && !binmode($loc) ) {
carp "Cannot binmode Local file $local: $!n";
$data->abort;
close($loc) unless $localfd;
return undef;
}
$buf = '';
my $blksize = ${*$ftp}{'net_ftp_blksize'};
local $; # Just in case
while (1) {
$blksize = $part_size if ( $part_size < $blksize );
last unless $len = $data->read( $buf, $blksize );
$where += $len;
if ( trEBCDIC && $ftp->type ne 'I' ) {
$buf = $ftp->toebcdic($buf);
$len = length($buf);
}
unless ( print $loc $buf ) {
carp "Cannot write to Local file $local: $!n";
$data->abort;
close($loc) unless $localfd;
return undef;
}
last unless $part_size -= $len;
}
close($loc) unless ($localfd);
$data->abort();
return $where;
}
package main;
#====== Fin de la méthode get_part ajoutée à Net::FTP
# programme de test
use File::Compare;
$|++;
my $ftp = Net::FTP->new('ftp.perl.org') or die $!;
$ftp->login('anonymous') or die $!;
$ftp->cwd('pub/cpan') or die $!;
$ftp->binary;
$ftp->get('RECENT.html'); # téléchargement en une partie
my $filesize = $ftp->size('RECENT.html');
my $offset = 0;
while ( $offset < $filesize ) { # téléchargement en parties de 50 ko
print "$offsetn";
$offset = $ftp->get_part('RECENT.html', # fichier cible
'RECENT2.html', # fichier local
$offset,
50 * 1024 # = 50 ko
);
}
$ftp->quit;
print "Les fichiers sont ",
compare('RECENT.html', 'RECENT2.html')?"differents
!":"identiques !";
__END__
Dans l'article <XnF98D9C5A12FCE4frantzdorsemainefree@212.27.60.40>,
dorsemaine.frantz@free.fr a dit...
Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca c'est
pas un probleme. Mais peut-on le recuperer par tranche de 1MO par
exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO
de façon à pouvoir reprendre le téléchargement sur plusieur jour si
nécéssaire ou alors faire en sorte de reprendre à l'endroit ou cela
c'est arrêter.
Ce n'est pas facile à faire.
Le module Net::FTP a bien une méthode
get( REMOTE_FILE [, LOCAL_FILE [, WHERE]])
qui permet de commencer le téléchargement à l'offset WHERE, mais rien
ne permet d'arrêter le transfert quand une certaine taille est
atteinte.
J'ai modifié la méthode get en une méthode get_part qui prend les
mêmes paramètres plus un : la taille du morceau de fichier que l'on
désire :
get_part( REMOTE_FILE, LOCAL_FILE, WHERE, SIZE )
ajoute à la fin du fichier LOCAL_FILE la partie de REMOTE_FILE qui
commence à l'offset WHERE et de taille SIZE. La méthode renvoie
l'offset du morceau suivant, si on veut continuer (ou undef en cas
d'erreur). Quand l'offset est supérieur ou égal à la taille du
fichier, tout le fichier est chargé. Le tranfert est toujours en mode
binary pour éviter les problèmes de CR/LF.
Le petit script suivant teste la fonction en comparant les fichiers
obtenus par get et get_part.
HTH
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
#====== Ajout d'une méthode get_part à Net::FTP
package Net::FTP;
sub get_part {
my ( $ftp, $remote, $local, $where, $part_size ) = @_;
my ( $loc, $len, $buf, $resp, $data );
local *FD;
my $localfd = ref($local) || ref( $local ) eq "GLOB";
( $local = $remote ) =~ s#^.*/## unless ( defined $local );
croak("Bad remote filename '$remote'n") if $remote =~ /[rn]/s;
$ftp->binary;
${*$ftp}{'net_ftp_rest'} = $where if defined $where;
my $rest = ${*$ftp}{'net_ftp_rest'};
delete ${*$ftp}{'net_ftp_port'};
delete ${*$ftp}{'net_ftp_pasv'};
$data = $ftp->retr($remote) or return undef;
if ($localfd) {
$loc = $local;
}
else {
$loc = *FD;
unless ( sysopen( $loc,
$local,
O_CREAT
| O_WRONLY
| ( $rest ? O_APPEND: O_TRUNC )) ) {
carp "Cannot open Local file $local: $!n";
$data->abort;
return undef;
}
}
if ( $ftp->type eq 'I' && !binmode($loc) ) {
carp "Cannot binmode Local file $local: $!n";
$data->abort;
close($loc) unless $localfd;
return undef;
}
$buf = '';
my $blksize = ${*$ftp}{'net_ftp_blksize'};
local $; # Just in case
while (1) {
$blksize = $part_size if ( $part_size < $blksize );
last unless $len = $data->read( $buf, $blksize );
$where += $len;
if ( trEBCDIC && $ftp->type ne 'I' ) {
$buf = $ftp->toebcdic($buf);
$len = length($buf);
}
unless ( print $loc $buf ) {
carp "Cannot write to Local file $local: $!n";
$data->abort;
close($loc) unless $localfd;
return undef;
}
last unless $part_size -= $len;
}
close($loc) unless ($localfd);
$data->abort();
return $where;
}
package main;
#====== Fin de la méthode get_part ajoutée à Net::FTP
# programme de test
use File::Compare;
$|++;
my $ftp = Net::FTP->new('ftp.perl.org') or die $!;
$ftp->login('anonymous') or die $!;
$ftp->cwd('pub/cpan') or die $!;
$ftp->binary;
$ftp->get('RECENT.html'); # téléchargement en une partie
my $filesize = $ftp->size('RECENT.html');
my $offset = 0;
while ( $offset < $filesize ) { # téléchargement en parties de 50 ko
print "$offsetn";
$offset = $ftp->get_part('RECENT.html', # fichier cible
'RECENT2.html', # fichier local
$offset,
50 * 1024 # = 50 ko
);
}
$ftp->quit;
print "Les fichiers sont ",
compare('RECENT.html', 'RECENT2.html')?"differents
!":"identiques !";
__END__
Dans l'article ,
a dit...
Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca c'est
pas un probleme. Mais peut-on le recuperer par tranche de 1MO par
exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO
de façon à pouvoir reprendre le téléchargement sur plusieur jour si
nécéssaire ou alors faire en sorte de reprendre à l'endroit ou cela
c'est arrêter.
Ce n'est pas facile à faire.
Le module Net::FTP a bien une méthode
get( REMOTE_FILE [, LOCAL_FILE [, WHERE]])
qui permet de commencer le téléchargement à l'offset WHERE, mais rien
ne permet d'arrêter le transfert quand une certaine taille est
atteinte.
J'ai modifié la méthode get en une méthode get_part qui prend les
mêmes paramètres plus un : la taille du morceau de fichier que l'on
désire :
get_part( REMOTE_FILE, LOCAL_FILE, WHERE, SIZE )
ajoute à la fin du fichier LOCAL_FILE la partie de REMOTE_FILE qui
commence à l'offset WHERE et de taille SIZE. La méthode renvoie
l'offset du morceau suivant, si on veut continuer (ou undef en cas
d'erreur). Quand l'offset est supérieur ou égal à la taille du
fichier, tout le fichier est chargé. Le tranfert est toujours en mode
binary pour éviter les problèmes de CR/LF.
Le petit script suivant teste la fonction en comparant les fichiers
obtenus par get et get_part.
HTH
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
#====== Ajout d'une méthode get_part à Net::FTP
package Net::FTP;
sub get_part {
my ( $ftp, $remote, $local, $where, $part_size ) = @_;
my ( $loc, $len, $buf, $resp, $data );
local *FD;
my $localfd = ref($local) || ref( $local ) eq "GLOB";
( $local = $remote ) =~ s#^.*/## unless ( defined $local );
croak("Bad remote filename '$remote'n") if $remote =~ /[rn]/s;
$ftp->binary;
${*$ftp}{'net_ftp_rest'} = $where if defined $where;
my $rest = ${*$ftp}{'net_ftp_rest'};
delete ${*$ftp}{'net_ftp_port'};
delete ${*$ftp}{'net_ftp_pasv'};
$data = $ftp->retr($remote) or return undef;
if ($localfd) {
$loc = $local;
}
else {
$loc = *FD;
unless ( sysopen( $loc,
$local,
O_CREAT
| O_WRONLY
| ( $rest ? O_APPEND: O_TRUNC )) ) {
carp "Cannot open Local file $local: $!n";
$data->abort;
return undef;
}
}
if ( $ftp->type eq 'I' && !binmode($loc) ) {
carp "Cannot binmode Local file $local: $!n";
$data->abort;
close($loc) unless $localfd;
return undef;
}
$buf = '';
my $blksize = ${*$ftp}{'net_ftp_blksize'};
local $; # Just in case
while (1) {
$blksize = $part_size if ( $part_size < $blksize );
last unless $len = $data->read( $buf, $blksize );
$where += $len;
if ( trEBCDIC && $ftp->type ne 'I' ) {
$buf = $ftp->toebcdic($buf);
$len = length($buf);
}
unless ( print $loc $buf ) {
carp "Cannot write to Local file $local: $!n";
$data->abort;
close($loc) unless $localfd;
return undef;
}
last unless $part_size -= $len;
}
close($loc) unless ($localfd);
$data->abort();
return $where;
}
package main;
#====== Fin de la méthode get_part ajoutée à Net::FTP
# programme de test
use File::Compare;
$|++;
my $ftp = Net::FTP->new('ftp.perl.org') or die $!;
$ftp->login('anonymous') or die $!;
$ftp->cwd('pub/cpan') or die $!;
$ftp->binary;
$ftp->get('RECENT.html'); # téléchargement en une partie
my $filesize = $ftp->size('RECENT.html');
my $offset = 0;
while ( $offset < $filesize ) { # téléchargement en parties de 50 ko
print "$offsetn";
$offset = $ftp->get_part('RECENT.html', # fichier cible
'RECENT2.html', # fichier local
$offset,
50 * 1024 # = 50 ko
);
}
$ftp->quit;
print "Les fichiers sont ",
compare('RECENT.html', 'RECENT2.html')?"differents
!":"identiques !";
__END__
(Jean-Louis MOREL) écrivait
news:45d9f9d9$0$15207$:Dans l'article ,
a dit...
Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca
c'est pas un probleme. Mais peut-on le recuperer par tranche de 1MO
par exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO
de façon à pouvoir reprendre le téléchargement sur plusieur jour si
nécéssaire ou alors faire en sorte de reprendre à l'endroit ou cela
c'est arrêter.
Ce n'est pas facile à faire.
Le module Net::FTP a bien une méthode
get( REMOTE_FILE [, LOCAL_FILE [, WHERE]])
qui permet de commencer le téléchargement à l'offset WHERE, mais rien
ne permet d'arrêter le transfert quand une certaine taille est
atteinte.
J'ai modifié la méthode get en une méthode get_part qui prend les
mêmes paramètres plus un : la taille du morceau de fichier que l'on
désire :
get_part( REMOTE_FILE, LOCAL_FILE, WHERE, SIZE )
ajoute à la fin du fichier LOCAL_FILE la partie de REMOTE_FILE qui
commence à l'offset WHERE et de taille SIZE. La méthode renvoie
l'offset du morceau suivant, si on veut continuer (ou undef en cas
d'erreur). Quand l'offset est supérieur ou égal à la taille du
fichier, tout le fichier est chargé. Le tranfert est toujours en mode
binary pour éviter les problèmes de CR/LF.
Le petit script suivant teste la fonction en comparant les fichiers
obtenus par get et get_part.
HTH
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
#====== Ajout d'une méthode get_part à Net::FTP
package Net::FTP;
sub get_part {
my ( $ftp, $remote, $local, $where, $part_size ) = @_;
my ( $loc, $len, $buf, $resp, $data );
local *FD;
my $localfd = ref($local) || ref( $local ) eq "GLOB";
( $local = $remote ) =~ s#^.*/## unless ( defined $local );
croak("Bad remote filename '$remote'n") if $remote =~ /[rn]/s;
$ftp->binary;
${*$ftp}{'net_ftp_rest'} = $where if defined $where;
my $rest = ${*$ftp}{'net_ftp_rest'};
delete ${*$ftp}{'net_ftp_port'};
delete ${*$ftp}{'net_ftp_pasv'};
$data = $ftp->retr($remote) or return undef;
if ($localfd) {
$loc = $local; }
else {
$loc = *FD;
unless ( sysopen( $loc, $local,
O_CREAT
| O_WRONLY ( $rest ? O_APPEND: O_TRUNC )) ) {
carp "Cannot open Local file $local: $!n"; $data->abort;
return undef; } }
if ( $ftp->type eq 'I' && !binmode($loc) ) {
carp "Cannot binmode Local file $local: $!n"; $data->abort;
close($loc) unless $localfd;
return undef;
}
$buf = '';
my $blksize = ${*$ftp}{'net_ftp_blksize'};
local $; # Just in case
while (1) {
$blksize = $part_size if ( $part_size < $blksize );
last unless $len = $data->read( $buf, $blksize );
$where += $len;
if ( trEBCDIC && $ftp->type ne 'I' ) {
$buf = $ftp->toebcdic($buf);
$len = length($buf); }
unless ( print $loc $buf ) {
carp "Cannot write to Local file $local: $!n"; $data->abort;
close($loc) unless $localfd;
return undef; }
last unless $part_size -= $len; }
close($loc) unless ($localfd); $data->abort();
return $where;
}
package main;
#====== Fin de la méthode get_part ajoutée à Net::FTP
# programme de test
use File::Compare; $|++;
my $ftp = Net::FTP->new('ftp.perl.org') or die $!;
$ftp->login('anonymous') or die $!;
$ftp->cwd('pub/cpan') or die $!;
$ftp->binary;
$ftp->get('RECENT.html'); # téléchargement en une partie
my $filesize = $ftp->size('RECENT.html');
my $offset = 0;
while ( $offset < $filesize ) { # téléchargement en parties de 50 ko
print "$offsetn";
$offset = $ftp->get_part('RECENT.html', # fichier cible
'RECENT2.html', # fichier local $offset,
50 * 1024 # = 50 ko ); }
$ftp->quit;
print "Les fichiers sont ", compare('RECENT.html',
'RECENT2.html')?"differents
!":"identiques !";
__END__
Bonsoir,
Merci pour la réponse qui marche mais je n'ai pas tout a fait le
résultat escompté.
Si j'interrompt le téléchargement, et que je le relance, il repart a
zéro. Il y à t-il un moyen de repartir de là ou on c'est arrêter.
jl_morel@bribes.org (Jean-Louis MOREL) écrivait
news:45d9f9d9$0$15207$426a74cc@news.free.fr:
Dans l'article <XnF98D9C5A12FCE4frantzdorsemainefree@212.27.60.40>,
dorsemaine.frantz@free.fr a dit...
Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca
c'est pas un probleme. Mais peut-on le recuperer par tranche de 1MO
par exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO
de façon à pouvoir reprendre le téléchargement sur plusieur jour si
nécéssaire ou alors faire en sorte de reprendre à l'endroit ou cela
c'est arrêter.
Ce n'est pas facile à faire.
Le module Net::FTP a bien une méthode
get( REMOTE_FILE [, LOCAL_FILE [, WHERE]])
qui permet de commencer le téléchargement à l'offset WHERE, mais rien
ne permet d'arrêter le transfert quand une certaine taille est
atteinte.
J'ai modifié la méthode get en une méthode get_part qui prend les
mêmes paramètres plus un : la taille du morceau de fichier que l'on
désire :
get_part( REMOTE_FILE, LOCAL_FILE, WHERE, SIZE )
ajoute à la fin du fichier LOCAL_FILE la partie de REMOTE_FILE qui
commence à l'offset WHERE et de taille SIZE. La méthode renvoie
l'offset du morceau suivant, si on veut continuer (ou undef en cas
d'erreur). Quand l'offset est supérieur ou égal à la taille du
fichier, tout le fichier est chargé. Le tranfert est toujours en mode
binary pour éviter les problèmes de CR/LF.
Le petit script suivant teste la fonction en comparant les fichiers
obtenus par get et get_part.
HTH
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
#====== Ajout d'une méthode get_part à Net::FTP
package Net::FTP;
sub get_part {
my ( $ftp, $remote, $local, $where, $part_size ) = @_;
my ( $loc, $len, $buf, $resp, $data );
local *FD;
my $localfd = ref($local) || ref( $local ) eq "GLOB";
( $local = $remote ) =~ s#^.*/## unless ( defined $local );
croak("Bad remote filename '$remote'n") if $remote =~ /[rn]/s;
$ftp->binary;
${*$ftp}{'net_ftp_rest'} = $where if defined $where;
my $rest = ${*$ftp}{'net_ftp_rest'};
delete ${*$ftp}{'net_ftp_port'};
delete ${*$ftp}{'net_ftp_pasv'};
$data = $ftp->retr($remote) or return undef;
if ($localfd) {
$loc = $local; }
else {
$loc = *FD;
unless ( sysopen( $loc, $local,
O_CREAT
| O_WRONLY ( $rest ? O_APPEND: O_TRUNC )) ) {
carp "Cannot open Local file $local: $!n"; $data->abort;
return undef; } }
if ( $ftp->type eq 'I' && !binmode($loc) ) {
carp "Cannot binmode Local file $local: $!n"; $data->abort;
close($loc) unless $localfd;
return undef;
}
$buf = '';
my $blksize = ${*$ftp}{'net_ftp_blksize'};
local $; # Just in case
while (1) {
$blksize = $part_size if ( $part_size < $blksize );
last unless $len = $data->read( $buf, $blksize );
$where += $len;
if ( trEBCDIC && $ftp->type ne 'I' ) {
$buf = $ftp->toebcdic($buf);
$len = length($buf); }
unless ( print $loc $buf ) {
carp "Cannot write to Local file $local: $!n"; $data->abort;
close($loc) unless $localfd;
return undef; }
last unless $part_size -= $len; }
close($loc) unless ($localfd); $data->abort();
return $where;
}
package main;
#====== Fin de la méthode get_part ajoutée à Net::FTP
# programme de test
use File::Compare; $|++;
my $ftp = Net::FTP->new('ftp.perl.org') or die $!;
$ftp->login('anonymous') or die $!;
$ftp->cwd('pub/cpan') or die $!;
$ftp->binary;
$ftp->get('RECENT.html'); # téléchargement en une partie
my $filesize = $ftp->size('RECENT.html');
my $offset = 0;
while ( $offset < $filesize ) { # téléchargement en parties de 50 ko
print "$offsetn";
$offset = $ftp->get_part('RECENT.html', # fichier cible
'RECENT2.html', # fichier local $offset,
50 * 1024 # = 50 ko ); }
$ftp->quit;
print "Les fichiers sont ", compare('RECENT.html',
'RECENT2.html')?"differents
!":"identiques !";
__END__
Bonsoir,
Merci pour la réponse qui marche mais je n'ai pas tout a fait le
résultat escompté.
Si j'interrompt le téléchargement, et que je le relance, il repart a
zéro. Il y à t-il un moyen de repartir de là ou on c'est arrêter.
(Jean-Louis MOREL) écrivait
news:45d9f9d9$0$15207$:Dans l'article ,
a dit...
Je shouaire recuperer un fichier sur un serveur FTP par Perl, ca
c'est pas un probleme. Mais peut-on le recuperer par tranche de 1MO
par exemple.
Le fichier fait 100MO, mais je veux le télécharger par tranche de 1MO
de façon à pouvoir reprendre le téléchargement sur plusieur jour si
nécéssaire ou alors faire en sorte de reprendre à l'endroit ou cela
c'est arrêter.
Ce n'est pas facile à faire.
Le module Net::FTP a bien une méthode
get( REMOTE_FILE [, LOCAL_FILE [, WHERE]])
qui permet de commencer le téléchargement à l'offset WHERE, mais rien
ne permet d'arrêter le transfert quand une certaine taille est
atteinte.
J'ai modifié la méthode get en une méthode get_part qui prend les
mêmes paramètres plus un : la taille du morceau de fichier que l'on
désire :
get_part( REMOTE_FILE, LOCAL_FILE, WHERE, SIZE )
ajoute à la fin du fichier LOCAL_FILE la partie de REMOTE_FILE qui
commence à l'offset WHERE et de taille SIZE. La méthode renvoie
l'offset du morceau suivant, si on veut continuer (ou undef en cas
d'erreur). Quand l'offset est supérieur ou égal à la taille du
fichier, tout le fichier est chargé. Le tranfert est toujours en mode
binary pour éviter les problèmes de CR/LF.
Le petit script suivant teste la fonction en comparant les fichiers
obtenus par get et get_part.
HTH
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
#====== Ajout d'une méthode get_part à Net::FTP
package Net::FTP;
sub get_part {
my ( $ftp, $remote, $local, $where, $part_size ) = @_;
my ( $loc, $len, $buf, $resp, $data );
local *FD;
my $localfd = ref($local) || ref( $local ) eq "GLOB";
( $local = $remote ) =~ s#^.*/## unless ( defined $local );
croak("Bad remote filename '$remote'n") if $remote =~ /[rn]/s;
$ftp->binary;
${*$ftp}{'net_ftp_rest'} = $where if defined $where;
my $rest = ${*$ftp}{'net_ftp_rest'};
delete ${*$ftp}{'net_ftp_port'};
delete ${*$ftp}{'net_ftp_pasv'};
$data = $ftp->retr($remote) or return undef;
if ($localfd) {
$loc = $local; }
else {
$loc = *FD;
unless ( sysopen( $loc, $local,
O_CREAT
| O_WRONLY ( $rest ? O_APPEND: O_TRUNC )) ) {
carp "Cannot open Local file $local: $!n"; $data->abort;
return undef; } }
if ( $ftp->type eq 'I' && !binmode($loc) ) {
carp "Cannot binmode Local file $local: $!n"; $data->abort;
close($loc) unless $localfd;
return undef;
}
$buf = '';
my $blksize = ${*$ftp}{'net_ftp_blksize'};
local $; # Just in case
while (1) {
$blksize = $part_size if ( $part_size < $blksize );
last unless $len = $data->read( $buf, $blksize );
$where += $len;
if ( trEBCDIC && $ftp->type ne 'I' ) {
$buf = $ftp->toebcdic($buf);
$len = length($buf); }
unless ( print $loc $buf ) {
carp "Cannot write to Local file $local: $!n"; $data->abort;
close($loc) unless $localfd;
return undef; }
last unless $part_size -= $len; }
close($loc) unless ($localfd); $data->abort();
return $where;
}
package main;
#====== Fin de la méthode get_part ajoutée à Net::FTP
# programme de test
use File::Compare; $|++;
my $ftp = Net::FTP->new('ftp.perl.org') or die $!;
$ftp->login('anonymous') or die $!;
$ftp->cwd('pub/cpan') or die $!;
$ftp->binary;
$ftp->get('RECENT.html'); # téléchargement en une partie
my $filesize = $ftp->size('RECENT.html');
my $offset = 0;
while ( $offset < $filesize ) { # téléchargement en parties de 50 ko
print "$offsetn";
$offset = $ftp->get_part('RECENT.html', # fichier cible
'RECENT2.html', # fichier local $offset,
50 * 1024 # = 50 ko ); }
$ftp->quit;
print "Les fichiers sont ", compare('RECENT.html',
'RECENT2.html')?"differents
!":"identiques !";
__END__
Bonsoir,
Merci pour la réponse qui marche mais je n'ai pas tout a fait le
résultat escompté.
Si j'interrompt le téléchargement, et que je le relance, il repart a
zéro. Il y à t-il un moyen de repartir de là ou on c'est arrêter.