【问题标题】:Fast calculation of the size and counting all files in a directory and subdirectories using python (cross platform)使用python(跨平台)快速计算大小并计算目录和子目录中的所有文件
【发布时间】:2013-01-31 22:26:12
【问题描述】:

如何在计算 python 跨平台中的所有文件的同时快速计算大目录的大小,这是我当前的代码,但在大文件数(超过 100000)上非常慢:

class filecounter:
    def count(self, scandir):
            global filescount
            global totalsize
            if not scandir[-1] == '/' or '\\':
                    scandir = scandir + '/'
            try:
                    for item in os.listdir(scandir):
                            if os.path.isdir(scandir + item):
                                    filecounter().count(scandir + item)
                            else:
                                    totalsize = totalsize + os.path.getsize(scandir +item)
                                    filescount = filescount + 1
            except WindowsError, IOError:
                    pass

需要全局

【问题讨论】:

  • 为什么不改用os.walk()
  • if not scandir[-1] == '/' or '\\' 不会按照你的想法去做。请改用if scandir[-1] not in ('/', '\\')
  • P.S.如果您正确编码,则不需要全局 - 让函数将这两个值作为元组或列表返回。
  • @user1469729 你确定需要捕获这些异常吗?如果没有 try-except 保护,它会运行得更快
  • P.P.S.你可能会被卡住。由于没有同时返回文件名和大小的函数,因此您需要查找每个文件的大小。随着目录变大,操作系统需要更长的时间来检索大小 - 一个经典的 n^2 问题。

标签: python file operating-system


【解决方案1】:

documentation for os.walk 几乎完全符合您的要求:

# from http://docs.python.org/2/library/os.html
import os
from os.path import join, getsize
for root, dirs, files in os.walk('python/Lib/email'):
    print root, "consumes",
    print sum(getsize(join(root, name)) for name in files),
    print "bytes in", len(files), "non-directory files"
    if 'CVS' in dirs:
        dirs.remove('CVS')  # don't visit CVS directories

根据您的需要进行更改非常简单:

import os
from os.path import join, getsize
size = 0
count = 0
for root, dirs, files in os.walk('.'):
    size += sum(getsize(join(root, name)) for name in files)
    count += len(files)
print count, size

【讨论】:

  • 谢谢,正是我需要的。
【解决方案2】:

如果你想为文件导航编写可移植的代码,你应该考虑使用os模块中的函数和常量(os.path.joinos.pathsepos.altsep,...)。

优化代码的一种方法是使用os.walk 函数删除递归和全局变量,但这不会给您带来太多好处。您将受到计算机 I/O 速度的限制。

def count(directory):
    totalsize = 0
    filecount = 0
    for dirpath, dirnames, filenames in os.walk(directory):
        for filename in filenames:
            try:
                totalsize += os.path.getsize(os.path.join(dirpath, filename))
                filecount += 1
            except OSError:
                pass
    return totalsize, filecount

大部分时间将花在系统调用上,以获取目录中的文件列表,并获取特定文件的大小。您可能可以使用 python 线程来并行化os.stat 的调用(由os.path.getsize 间接调用)。这一次,python 线程将在执行系统调用时释放 GIL 时工作。

【讨论】:

    猜你喜欢
    • 2010-11-26
    • 1970-01-01
    • 2011-02-28
    • 2015-06-28
    • 2015-06-27
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多