Pythonでファイル、ディレクトリ(フォルダ)のサイズを取得

Modified: | Tags: Python, ファイル処理

Pythonでは、os.path.getsize()を使ってファイルのサイズをバイトで取得できる。さらに、os.scandir()を利用すると、ディレクトリ(フォルダー)に含まれているファイルのサイズの合計を取得することも可能。

サイズではなくタイムスタンプ(作成日時や更新日時)を取得したい場合は以下の記事を参照。

ファイルのサイズ取得: os.path.getsize()

ファイルのサイズ(容量)はos.path.getsize()で取得できる。

引数にサイズを取得したいファイルのパス(パス文字列やpathlib.Pathなどのpath-like object)を指定する。

import os

print(os.path.getsize('data/src/lena_square.png'))
# 473831

ディレクトリ(フォルダ)のサイズ取得: os.scandir()を利用

ディレクトリ(フォルダ)に含まれているファイルのサイズの合計を算出するには、os.scandir()を使う。

この関数はPython3.5で追加されたものなので、それより前のバージョンではos.listdir()を使う。os.listdir()の例は後述。

以下のような関数を定義する。

import os

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

print(get_dir_size('data/src'))
# 56130856

os.scandir()は、指定したディレクトリ内のファイルやディレクトリに対応するos.DirEntryオブジェクトのイテレータを返す。

os.DirEntryオブジェクトに対して、is_file(), is_dir()メソッドでファイルかディレクトリかを判定する。ファイルの場合はstat()メソッドが返すstat_resultオブジェクトのst_size属性でサイズを取得、ディレクトリの場合はこの関数を再帰的に呼び出して、すべてのサイズを加算して合計サイズを算出している。

デフォルトでは、is_file()はファイルへのシンボリックリンク、is_dir()はディレクトリへのシンボリックリンクに対してもTrueを返す。シンボリックリンクを無視したい場合は、is_file(), is_dir()の引数follow_symlinksFalseとする。

また、サブディレクトリを辿る必要がなければ以下の部分を削除すればよい。

            elif entry.is_dir():
                total += get_dir_size(entry.path)

上の関数は引数にファイルのパスを渡すとエラーになる。ファイルでもディレクトリでもそのサイズを返すようにするには、以下のようなラッパー関数を書く。

def get_size(path='.'):
    if os.path.isfile(path):
        return os.path.getsize(path)
    elif os.path.isdir(path):
        return get_dir_size(path)

print(get_size('data/src'))
# 56130856

print(get_size('data/src/lena_square.png'))
# 473831

ディレクトリ(フォルダ)のサイズ取得: os.listdir()を利用

Python3.4以前(Python3.5より前)にはos.scandir()が無いので、os.listdir()を使う。

以下のような関数を定義する。

import os

def get_dir_size_old(path='.'):
    total = 0
    for p in os.listdir(path):
        full_path = os.path.join(path, p)
        if os.path.isfile(full_path):
            total += os.path.getsize(full_path)
        elif os.path.isdir(full_path):
            total += get_dir_size_old(full_path)
    return total

print(get_dir_size_old('data/src'))
# 56130856

基本的な考え方はos.scandir()の場合と同じ。

os.listdir()で取得できるのはファイル名(ディレクトリ名)のリスト。それぞれのファイル名やディレクトリ名を親ディレクトリのパスとos.path.join()で結合してフルパスを作成している。

対象がシンボリックリンクの場合、os.path.isfile()os.path.isdir()はその実体に対して判定するので、シンボリックリンクを無視したいときは、シンボリックリンクに対してTrueを返すos.path.islink()と組み合わせて条件判定をする。

os.scandir()の場合と同様、サブディレクトリを辿る必要がなければ以下の部分を削除すればよい。

        elif os.path.isdir(full_path):
            total += get_dir_size_old(full_path)

上の関数は引数にファイルのパスを渡すとエラーになる。ファイルでもディレクトリでもそのサイズを返すようにするには、以下のようなラッパー関数を書く。

def get_size_old(path='.'):
    if os.path.isfile(path):
        return os.path.getsize(path)
    elif os.path.isdir(path):
        return get_dir_size_old(path)

print(get_size_old('data/src'))
# 56130856

print(get_size_old('data/src/lena_square.png'))
# 473831

関連カテゴリー

関連記事