Python独習!

習得したPython知識をペイフォワード

Pythonでディレクトリ内のフォルダのサイズを出力

私の職場では、共有サーバーの容量が上限ギリギリなので不要なものをバックアップサーバーに移すように、と緊急指示が出ることがある。そんなときにどのフォルダが容量を食っているのか調べたくなる。
指定したディレクトリからさらに1階層下のディレクトリの内容をリストアップして、それぞれの容量を出力するプログラムを作った。

結果

左は対象のディレクトリをコマンドプロンプトtree /fコマンドで出力したもの。右はプログラム実行結果。
ちゃんとすべてのフォルダとファイルをスキャンできていることがわかる。対象ディレクトリはテスト用に作っただけで中身は空っぽのため、0.00GBと表示されている。※会社の共有サーバーで動作検証済み。
f:id:greenhornprofessional:20200115222246p:plain

プログラム

Pyhton 3.8.1

import pathlib
import os

main_path = pathlib.WindowsPath(r'C:\First layer')  #rオプションで絶対パスが記述通りに読み込まれる。
main_files = os.listdir(main_path)                  #main_path直下にある要素(main_file)をリスト化する。要素:ファイル/フォルダのこと。

#指定パスがファイルならそのサイズをtotalに加算、フォルダならそのフォルダに対して同じことをする。
def get_dir_size(path):
    total = 0
    with os.scandir(path) as it:
        for entry in it:
            if entry.is_file():
                total += entry.stat().st_size
            elif entry.is_dir():
                total += get_dir_size(entry.path)
    return total

#指定パスがリンクなら0を返す、ファイルならそのファイルサイズを返す、フォルダならget_dir_sizeに渡す。
def get_size(path):
    try:
        if os.path.islink(path):
            return 0
        elif os.path.isfile(path):
            return os.path.getsize(path)
        elif os.path.isdir(path):
            return get_dir_size(path)
        
    except PermissionError:
        print('Permission denied : ' + path)
    except FileNotFoundError:
        print('File not found : ' + path)
    except NotADirectoryError:
        print('Not a directory : ' + path)
    except OSError:
        print('Smething wrong  : ' + path)
    return 0                                        #エラーが起きたときは0を返す。


for main_file in main_files:                        #main_path直下にある要素(main_file)をforで1個ずつ処理する。
    sub_path = os.path.join(main_path, main_file)   #取り出した要素の絶対パス(sub_path)を生成する。
    try:
        if os.path.isdir(sub_path):                 #取り出した要素(main_file)がフォルダなら以下の処理をする。
            sub_files = os.listdir(sub_path)        #sub_path直下にある要素(sub_file)をリスト化する。
            print(main_file)                        #要素(main_file)の名前を出力する。
            sumSize = 0
            for sub_file in sub_files:                  #sub_path直下にある要素(sub_file)をforで1個ずつ処理する。
                x = get_size(os.path.join(sub_path, sub_file)) / 1024 / 1024 / 1024  #取り出した要素(sub_file)の絶対パスをget_sizeに渡し、戻ってきた値をGBに換算する。
                sumSize += x                            #要素(sub_file)のサイズを総和する。
                print(">%s, %.2f GB" % (sub_file, x))   #各要素(sub_file)の名前とサイズを出力する。
            print(">>Sum: %.2f GB" % sumSize)           #要素(sub_file)のサイズの総和を出力する。
            print()
        else:                                       #取り出した要素がフォルダ以外なら以下の処理をする。
            print(main_file)                        #サイズは無視するものとして、要素の名前だけ出力する。
            print()
    except PermissionError:
        print('Permission denied : ' + sub_path)
    except FileNotFoundError:
        print('File not found : ' + sub_path)
    except NotADirectoryError:
        print('Not a directory : ' + sub_path)
    except OSError:
        print('Smething wrong  : ' + sub_path)

[05_folderSize_002.py]

/* -----codeの行番号----- */