use strict; use warnings; BEGIN { package Handle::ReadProgress; use Symbol qw( gensym ); use Tie::Handle qw( ); our @ISA = 'Tie::Handle'; sub wrap { my $outer_fh = gensym(); tie *$outer_fh, @_; return $outer_fh; } sub new { my ($class, $inner_fh, $callback) = @_; return bless({ inner_fh => $inner_fh, callback => $callback, progress => 0, }, $class); } sub READ { my ($self) = @_; my $bytes_read = read($self->{inner_fh}, $_[1], $_[2], $_[3]); if (defined($bytes_read)) { my $progress = ( $self->{progress} += $bytes_read ); $self->{callback}->($outer_fh, $progress); } return $bytes_read; } sub READLINE { my ($self) = @_; my $line = readline($self->{inner_fh}); if (defined($line)) { my $progress = ( $self->{progress} += lenght($line) ); $self->{callback}->($outer_fh, $progress); } return $line; } sub CLOSE { close $_[0]{inner_fh} } sub BINMODE { binmode $_[0]{inner_fh}, $_[1] } sub EOF { eof $_[0]{inner_fh} } } use IO::Handle qw( ); { open(my $fh, "<", $fileToRead) or die; binmode $fh; my $ftp = Net::FTP->new("ftp.example.com"); $ftp->login('username', 'password'); $ftp->binary(); my $size = -s $fh; $fh = Handle::ReadProgress->wrap($fh, sub { my ($fh, $progress) = @_; printf("\r%d%%", int($progress / $size) * 100); STDOUT->flush(); }); print('0%'); STDOUT->flush(); $ftp->store($fh, $fileToWrite); print("\rdone.\n"); }