Quickly calculate folder size in Python on Windows

I am looking for a quick way to calculate folder size in Python on Windows. This is what I have so far:

def get_dir_size(path):
  total_size = 0
  if platform.system() == 'Windows':
    try:
      items = win32file.FindFilesW(path + '\\*')
    except Exception, err:
      return 0

    # Add the size or perform recursion on folders.
    for item in items:
      attr = item[0]
      name = item[-2]
      size = item[5]

      if (attr & win32con.FILE_ATTRIBUTE_DIRECTORY) and \
         not (attr & win32con.FILE_ATTRIBUTE_SYSTEM):  # skip system dirs
        if name not in DIR_EXCLUDES:
          total_size += get_dir_size("%s\\%s" % (path, name))

      total_size += size

  return total_size

This is not enough if the folder size exceeds 100G. Any ideas how to improve it?

On a fast machine (2Ghz + - 5G RAM) it took 72 seconds to move through 422GB in 226 001 files and 12 043 folders. It takes 40 seconds using the explorer properties option.

I know that I'm a little greedy, but I hope for a better solution.

Laurent Luce

+5
source share
6 answers

, 90% FindFilesW(). , Python .

( FindFilesW) , DIR_EXCLUDES - , [] , sys.platform . , , 1-2% .

DIR_EXCLUDES = set(['.', '..'])
MASK = win32con.FILE_ATTRIBUTE_DIRECTORY | win32con.FILE_ATTRIBUTE_SYSTEM
REQUIRED = win32con.FILE_ATTRIBUTE_DIRECTORY
FindFilesW = win32file.FindFilesW

def get_dir_size(path):
    total_size = 0
    try:
        items = FindFilesW(path + r'\*')
    except pywintypes.error, ex:
        return total_size

    for item in items:
        total_size += item[5]
        if (item[0] & MASK == REQUIRED):
            name = item[8]
            if name not in DIR_EXCLUDES:
                total_size += get_dir_size(path + '\\' + name)

    return total_size

API . , , , . , FindFirstChangeNotification API - . , ( ), , , ( ), , .

: , , Windows XP . ( ) Windows, C:\ Alt-Enter, . ( ) 40 , 20- . , , Windows, , .

+5

, os.walk. , .

, :

import os

def get_dir_size(root):
    size = 0
    for path, dirs, files in os.walk(root):
        for f in files:
            size +=  os.path.getsize( os.path.join( path, f ) )
    return size
+1

Windows , , win32file.FindFilesIterator " win32file.FindFiles, ". ?

+1

. , , ... , . ...

- ( , ), ( ... , , , ).

, , , , , , . Windows.; -)

+1

:

try:
  items = win32file.FindFilesW(path + '\\*')
except Exception, err:
  return 0

Exception handling can add significant time to your algorithm. If you can specify the path in different ways, in a way that you always know, it is safe and thus eliminate the need to catch exceptions (for example, first check to see if this path is a folder before searching for files in this folder), you can find significant acceleration.

+1
source
# Size of File Folder/Directory in MBytes

import os

# pick a folder you have ...
folder = 'D:\\zz1'
folder_size = 0
for (path, dirs, files) in os.walk(folder):
  for file in files:
    filename = os.path.join(path, file)
    folder_size += os.path.getsize(filename)

print "Folder = %0.1f MB" % (folder_size/(1024*1024.0))
0
source

All Articles