Как сообщить о прогрессе при обработке большого файла? - PullRequest
0 голосов
/ 29 февраля 2012

Как я могу сообщать, например, каждые пять секунд, сколько файлов обрабатывается?Я думаю, мне нужен поток, но как он контролируется?

#!/bin/env python
# -*- coding: utf8 -*-

import os
import sys
import logging
import hashlib

logger = logging.getLogger()
FORMAT = "%(asctime)s %(levelname)s: %(message)s"
logging.basicConfig(format=FORMAT, level=logging.DEBUG, datefmt="%H:%M:%S")

class fileScanner:
  readBytes = 0
  lastReadBytes = 0
  fileSize = 0  
  reportSeconds = 5

  def scanFile(self, filePath):
    self.readBytes = 0
    self.lastReadBytes = 0

    logging.getLogger()
    self.fileSize = os.path.getsize(filePath)

    with open(filePath, 'rb') as f:
      m = hashlib.sha512()
      while True:
        data = f.read(1024)
        if not data:
          break
        self.readBytes += len(data)
        m.update(data)
      return m.hexdigest()
    raise IOError("Couldn't process file '%s'" % filePath)

  def reportProcess(self):
    logging.getLogger()
    percent = float((self.readBytes / self.fileSize) * 100)
    secAvg = (self.readBytes - self.lastReadBytes) / self.reportSeconds
    estimatedTime = (self.fileSize - self.readBytes) / secAvg
    logging.info("%s%% (%s / %s bytes) read in average of %s MB / sec. Estimated time left: %s seconds." % (percent, self.readBytes, self.fileSize, secAvg, estimatedTime))
    self.lastReadBytes = self.readBytes


if __name__ == "__main__":
  fs = fileScanner()
  hash = fs.scanfile('largefile.dat')

Как запустить и завершить reportProcess ()?

Да, я знаю, что вычисления там, вероятно, неверны.

Ответы [ 2 ]

1 голос
/ 29 февраля 2012

Просто вызывайте reportProcess в цикле чтения каждые 5 секунд, например,

lastTime = time.time()
while True:
    data = f.read(1024)
    if not data:
      break
    self.readBytes += len(data)
    if time.time() - lastTime > 5:
        self.reportProcess()
        lastTime = time.time()

Unreleated: почему вы используете атрибуты уровня класса, обычно они должны быть на уровне экземпляра, например

class FileScanner:
  def __init__(self):
      self.readBytes = 0
      self.lastReadBytes = 0
0 голосов
/ 29 февраля 2012

Не могли бы вы просто вызвать reportProcess() внутри функции scanFile() внутри цикла while.Например, каждый прочитанный x байтов вы вызываете reportProcess() (добавьте условие в цикл while).Это решит вашу проблему?

...