【问题标题】:How to report progress while processing large file?如何在处理大文件时报告进度?
【发布时间】:2012-02-29 18:05:32
【问题描述】:

例如,如何每五秒报告一次处理了多少文件?我想我需要线程,但它是如何控制的?

#!/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()?

是的,我知道那里的计算可能是错误的。

【问题讨论】:

  • 当您执行 fs=fileScanner 时,您不会创建 fileScanner 的实例。您只是将类对象分配给 fs。它应该是 fs=fileScanner()。

标签: python multithreading logging command-line-interface


【解决方案1】:

只需在读取循环中每 5 秒调用一次 reportProcess,例如

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()

不相关:为什么要使用类级别的属性,通常它们应该在实例级别,例如

class FileScanner:
  def __init__(self):
      self.readBytes = 0
      self.lastReadBytes = 0

【讨论】:

  • 我使用类级属性来表示实例将拥有哪些属性并将它们公开给 sphinx-doc
【解决方案2】:

您可以从while 循环内的scanFile() 函数内部调用reportProcess()。例如,每读取一个 x 字节,您就调用 reportProcess()(在 while 循环中添加条件)。这能解决你的问题吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多