Skip to content

Instantly share code, notes, and snippets.

@NHellFire
Created December 22, 2016 03:20
Show Gist options
  • Save NHellFire/e5c0d69b238bf5f004dd469fd4a643f7 to your computer and use it in GitHub Desktop.
Save NHellFire/e5c0d69b238bf5f004dd469fd4a643f7 to your computer and use it in GitHub Desktop.
Python copyfileobj with progress bar
from time import time
import sys
def mksize (bytes):
suffixes = ("B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
suffixesLen = len(suffixes)
for i in range(suffixesLen):
if bytes < pow(1000, i + 1) or i + 1 == suffixesLen:
return "%.2f %s" % (float(bytes) / pow(1024, i), suffixes[i])
def copyfileobj (fsrc, fdst, bufsize=16384, filesize=None):
progress = 0
percent = 0
lastpercent = 0
lasttime = time()
lastprogress = 0
lastprogress_speed = 0
speed = 0
eta = None
while True:
buf = fsrc.read(bufsize)
if not buf:
break
fdst.write(buf)
if filesize:
progress += len(buf)
timenow = time()
elapsed = (timenow - lasttime)
if elapsed >= 1: # Average it over 1 second
speed = ((progress - lastprogress_speed) / elapsed) * (1/elapsed)
lasttime = timenow
lastprogress_speed = progress
eta = "%d secs" % ((filesize - progress) / speed)
percent = int((float(progress) / filesize) * 100)
if percent != lastpercent:
bar = ""
barlen = 50
if percent == 100:
bar = "=" * barlen
else:
scaled_percent = percent/(100/barlen)
for i in range(barlen):
if i < scaled_percent-1:
bar += "="
elif i < scaled_percent:
bar += ">"
else:
bar += " "
print "%d%% [%s] %s (%s/s) %s \r" % (percent, bar, mksize(progress), mksize(speed) if speed else "-.-- MB", "eta " + eta if eta else ""),
sys.stdout.flush()
lastpercent = percent
lastprogress = progress
print
# Example usage:
from os.path import getsize
filename = "/home/user/largefile.bin"
copyfileobj(open(filename, "rb"), open("/dev/null", "wb"), 16384, getsize(filename))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment