Ruby Net::FTP Progress Bar
Does anyone know of a way to get a status 开发者_运维百科update from ruby's Net::FTP library while downloading a file? I am trying to implement a web interface that shows a progress bar for percentage remaining when downloading a file from a remote ftp server.
For future reference - I stumbled upon a solution:
filesize = ftp.size(filename)
transferred = 0
p "Beginning download, file size: #{filesize}"
ftp.getbinaryfile(filename, "#{SOURCE_IMPORT_DIRECTORY}/#{filename}", 1024) { |data|
transferred += data.size
percent_finished = ((transferred).to_f/filesize.to_f)*100
p "#{percent_finished.round}% complete"
}
ftp.close
I expanded on the answers given by @smnirven and @theoretick to create a fixed size progress bar that fills up as it completes so that you can have a visual idea of how complete the progress is:
def getprogress(ftp,file,local_path)
transferred = 0
filesize = ftp.size(file)
ftp.get(file, local_path, 1024) do |data|
transferred += data.size
percent = ((transferred.to_f/filesize.to_f)*100).to_i
finished = ((transferred.to_f/filesize.to_f)*30).to_i
not_finished = 30 - finished
print "\r"
print "#{"%3i" % percent}%"
print "["
finished.downto(1) { |n| print "=" }
print ">"
not_finished.downto(1) { |n| print " " }
print "]"
end
print "\n"
end
ouput:
Executing gather for: ruby
Going to public ftp - ftp.ruby-lang.org
File list for /pub/ruby/2.0/:
ruby-2.0.0-p647.tar.gz
Downloading: ruby-2.0.0-p647.tar.gz
100%[==============================>]
The key with this example is the print "\r" in order to rewrite the line.
I built on @smnirven's excellent approach for a bit less noisy progress with 100-dot progression:
filesize = ftp.size(filename)
transferred = 0
notified = false
ftp.getbinaryfile(filename, full_local_path, 1024) do |data|
transferred += data.size
percent_finished = (((transferred).to_f/filesize.to_f)*100)
if percent_finished.to_s.include?('.0')
print "." if notified == false
notified = true
else
notified = false
end
end
ftp.close
output:
[progress] Downloading CBSA boundaries...
..........................................................................
..........................
[progress] Finished!
Just a small update to the code to make the output little bit cleaner.
filesize = ftp.size(FILENAME)
transferred = 0
percent_finished = -9999
ftp.gettextfile(FILENAME, File.basename(FILENAME)) { |data|
transferred += data.size
temp = (((transferred).to_f/filesize.to_f)*100).round
if percent_finished < temp
percent_finished = temp
STDOUT.write "\r Download progress: #{percent_finished.round}% completed"
end
}
ftp.close
精彩评论