@anogayales: Ich würde davon abraten die Blockgrösse zu berechnen. Wenn die Datei <100 Bytes ist kommt da 0 heraus, das ist sicher lustig.
Wenn sie >100 aber immer noch klein ist, werden in jedem Schleifendurchlauf nur wenige Bytes gelesen, das ist unsinnig.
Das ist auch extrem verwirrend ausgedrückt mit dem `seek()`. Lies einfach in einer Schleife solange Blöcke mit einer festen Grösse bis keine Daten mehr kommen. Dann sparst Du Dir auch irgendwelche Spässe mit dem berechnen von der Blockgrösse und dem letzten Block. Da stimmt wahrscheinlich auch irgendetwas nicht, denn wenn Du die ``while``-Scheife verlässt, dann ist `counter` ja schon grösser oder gleich der Dateigrösse, also ist zu dem Zeitpunkt schon alles verarbeitet.
Die Schleife würde ohne diesen Test ewig weiterlaufen, weil ein `read()` am Ende einer Datei eine leere Zeichenkette liefert. Immer und immer wieder. *Das* ist aber auch ein prima Abbruchkriterium.
Du darfst den `counter` auch nicht einfach um `stepsize` erhöhen, denn ein `read(stepsize)` kann auch weniger als `stepsize` Bytes liefern -- nämlich am Ende der Datei wenn gar nicht mehr genug Bytes da sind, oder eben ganz am Ende wenn immer 0 Bytes gelesen werden.
Code: Alles auswählen
import os
from functools import partial
from hashlib import sha224
def hash_file(file_obj,
hasher,
callback=lambda byte_count: None,
blocksize=4096):
byte_count = 0
for block in iter(partial(file_obj.read, blocksize), ''):
hasher.update(block)
byte_count += len(block)
callback(byte_count)
return hasher.hexdigest()
def main():
filename = 'test.iso'
filesize = os.path.getsize(filename)
def print_progress(byte_count):
print '\r%d/%d %6.2f' % (byte_count,
filesize,
100.0 * byte_count / filesize),
with open(filename) as iso_file:
print hash_file(iso_file, sha224(), print_progress)