Python
python3

ディレクトリに対してos.path.getsize()をすると間違った値が返される

ディレクトリ内のファイルの合計サイズ(Windowsで言うところのフォルダを右クリック→プロパティで表示されるサイズ)を取得したいとします。素直にディレクトリに対してos.path.getsize()とすると明らかに異なる値が返されました。

+dir # このディレクトリ以下の合計サイズがほしい
 -file1
 -file2
 -::

環境:Windows7、Python3.6

dirフォルダをエクスプローラーで見たときこうだったとします
python_dir.png

ダメな例

Python
import os.path

size = os.path.getsize("dir")
print(size) #12288←異なる値

os.path.getsize()はバイト数で返されるので、明らかに小さい値です。これはディレクトリのinodeが参照されているためです(後述)。

良い例

glob.glob()等でファイルリストを取得して、ファイルサイズを合計しましょう。

Python
import os.path
import glob

files = glob.glob(os.path.join("dir", "**"), recursive = True)
size = sum((os.path.getsize(f) for f in files if not os.path.isdir(f)))
print(size) #13869976←正しい値

正しい値が取得できました。Python3.5以降ではglob.glob()の引数に**を指定、recursive=Trueとすることで、サブディレクトリを再帰的に取得することができます(詳細)。
対象のディレクトリ以下にディレクトリが含まれる場合は、if not os.path.isdir(f)のフィルターを入れても入れなくても、若干誤差が出る(エクスプローラーの値とは数KB異なる)ことがありますので、これは好みで入れてください。

簡単な解説

StackOverFlowにありました。

This value (4624B) represents the size of the file that describes that directory. Directories are described as inodes (http://en.wikipedia.org/wiki/Inode) that hold information about the files and directories it contains.

ディレクトリは、それ以下に含まれるファイルやディレクトリの情報を持っているinodeとして記されており、os.path.getsize("dir")としたときの値はそのinodeのサイズを参照しているとのこと。

Windowsにはinodeはありませんが、NTFSに似たようなシステムはあるそうです。

関連:os.path.getsize Returns Incorrect Value?
https://stackoverflow.com/questions/10404534/os-path-getsize-returns-incorrect-value
windowsのファイルシステムにiノードという概念はないですよね??
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1334197648