Python Pythonでディレクトリ内の全ファイルの合計サイズを取得|階層構造のサブディレクトリの中も探索

Pythonでディレクトリ内の全ファイルの合計サイズを取得|階層構造のサブディレクトリの中も探索

python_getsize_dir_all-file_walk_topimage

Pythonでディレクトリ内にあるファイルの合計サイズを取得したいけど、いろいろな形式のファイルが混ざってたり、サブディレクトリもある場合はどうのように処理したら良いのでしょう。

今回は、Pythonで指定したディレクトリ内にある全ファイルの合計サイズを取得する方法を解説します。

Pythonでディレクトリ内のファイルサイズを取得するのは簡単ですが、サブディレクトリもファイルがある場合はちょっとしたテクニックが必要

このテクニックを知らないとif文でサブディレクトリの有無を判別するなど面倒な処理が必要になります。

Pythonには、サブディレクトリのファイルまで探索してくれる機能があり、それを利用すればif文でサブディレクトリの有無を判別する事なく、階層構造のディレクトリにある全ファイルの合計サイズを取得する事ができます。

■この記事で紹介するファイルのサイズを取得する方法

・指定したファイルのサイズを取得する方法
・ディレクトリ内の全ファイルの合計サイズを取得する方法
・ファイルの拡張子を限定して合計サイズを取得する方法
・globモジュールを使ってファイルの拡張子を限定する方法
・サブディレクトリのファイルを含めた合計サイズを取得する方法


Pythonでファイルのサイズを取得

はじめに、Pythonで指定したファイルのサイズを取得するにはどうのようにしたら良いのでしょう。

次のディレクトリにある「etixAutoSalon.pdf」のファイルサイズを取得したいと思います。

Pythonでファイルのサイズを取得


Pythonでファイルのサイズ取得には osモジュールの os.path.getsize() を使用します。

os.path.getsize() に「etixAutoSalon.pdf」のパスを指定。print出力します。

import os

file_path = "D:/liquidjumper/etixAutoSalon.pdf"

print(os.path.getsize(file_path))


実行:

ファイル「etixAutoSalon.pdf」のサイズが取得できました。単位はbyte

630261



>>【Udemy】Python 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイルを学ぶオンライン講座

Pythonのos.listdir()を使ってディレクトリ内の全ファイルの合計サイズを取得

Pythonで指定したファイルのサイズを取得する方法が分かったので、次は指定したディレクトリ内のファイルの合計サイズを取得してみましょう。

手順としては、

1)最初にディレクトリ内の一覧をリストで取得
2)for文でリストから取り出しos.path.getsize()でサイズを取得
3)取得したファイルのサイズを合計する


Pythonでディレクトリ内の一覧を取得するには os.listdir() を使用します

os.listdir()にディレクトリのパスを指定、返されるディレクトリ内の一覧のリストを[dir_list]に代入します。
for文で[dir_list]からディレクトリ名・ファイル名を取り出し、os.path.join()でフルパスにし変換、os.path.getsize()にフルパスを指定、ファイルサイズを取得します。

import os 

dir_path = "D:/liquidjumper" 

dir_list = os.listdir(dir_path)

full_size = 0

for file_name_i in dir_list:
 file_size = os.path.getsize(os.path.join(dir_path,file_name_i))
 full_size += file_size

print(full_size)


実行:

ディレクトリ “D:/liquidjumper”にあるファイルの合計サイズ が取得されました。

651406

ファイルの拡張子[.txt]に限定してファイルの合計サイズを取得

ディレクトリ “D:/liquidjumper”にある全ファイルの合計サイズ は取得できましたが、指定したファイル形式だけのサイズを取得するにはどうのようにしたら良いのでしょう。

Pythonは、os.pathモジュールの関数 splitext() でファイルパスから拡張子を分割する事ができます。

この関数でファイル名から拡張子を取得、if文で条件分岐させれば、指定したファイル形式だけのサイズが取得できそう。

for文で[dir_list]から取り出したファイル名を、os.path.splitext()[1]に指定、拡張子を取得。
if文で拡張子[.txt]と合致した場合のみ、os.path.getsize()でファイルサイズを取得する。

import os

dir_path = "D:/liquidjumper" 

dir_list = os.listdir(dir_path) 

full_size = 0 

for file_name_i in dir_list: 

  if ".txt" == os.path.splitext(file_name_i)[1]: ## os.path.splitext()[1]で拡張子を取得
    file_size = os.path.getsize(os.path.join(dir_path,file_name_i)) 
    full_size += file_size 

print(full_size)


実行:

拡張子[.txt]のファイルだけの合計サイズが取得できました。

359


Python3のos.scandir()を使ってディレクトリ内の全ファイルの合計サイズを取得

前項ではos.listdir()でディレクトリの一覧を取得しましたが、Python 3では os.scandir() でもディレクトリの一覧が取得できます。

os.scandir() を使うと、ディレクトリ・ファイルの属性・情報も併せて取得できるため、処理の自由度が高く、より簡単にディレクトリ内の一覧を取得することができます。

※ os.scandir()はPython3.5で追加されたものなので、それより前のバージョンのPythonはos.listdir()を使ってください。

with構文を使い、os.scandir()で取得したディレクトリの要素を変数[dir_list]に代入。
for文で[dir_list]から順番に取り出し file_name.pathでフルパスの情報を参照。
その参照したフルパスをos.path.getsize()に指定、ファイルサイズを取得します。

import os  

dir_path = "D:/liquidjumper"  

full_size = 0  

with os.scandir(dir_path) as dir_list: 

    for file_name in dir_list:  
        file_size = os.path.getsize(file_name.path)  
        full_size += file_size 

print(full_size)


実行:

os.scandir()を使ってディレクトリ内にあるファイルの合計サイズが取得できました。

651406


globモジュールでファイルの拡張子を限定してファイルの合計サイズを取得

os.pathモジュールの関数 splitext() でファイルパスから拡張子を取得しif文で条件分岐させ、指定したファイル形式だけのサイズを取得する方法を紹介しましたが、globモジュールを使えばもっと簡単にファイル形式を限定する事ができます。

指定するディレクトリパスにワイルドカード「*txt」を追記。これで拡張子[.txt]のファイルだけが対象になります。
glob.glob()にワイルドカードを追記したディレクトリパスを指定、返される[.txt]ファイルのリストを[txt_files]に代入。
for文で[txt_files]から[.txt]ファイルを取り出し、os.path.getsize()でファイルサイズを取得します。

import os
import glob 

dir_path = "D:/liquidjumper/*txt" ##ワイルドカードを設定「*txt」

txt_files = glob.glob(dir_path)

full_size = 0

for file_name_i in txt_files: 
    file_size = os.path.getsize(file_name_i)
    full_size += file_size  

print(full_size)


実行:

拡張子[.txt]のファイルだけの合計サイズが取得できました。

359

os.walk()でサブディレクトリのファイルも含めた合計サイズを取得

これまで、指定したディレクトリにあるファイルの合計サイズを取得する事はできましたが、これらの方法には問題があります。

os.listdir()・os.scandir()・glob.glob()

何れの方法も指定したディレクトリ直下にあるファイルのみが対象で、サブディレクトリの中にあるファイルは非対象。

これでは、サブディレクトリがある階層構造のディレクトリの場合、正確なファイルサイズを取得することができません。

次のような階層のディレクトリの場合、「D:/liquidjumper」を指定すると「D:/liquidjumper」直下のファイルのサイズしか取得できず、「image」と「video/mov」の中にあるファイルのサイズはカウントされません。

D:/liquidjumper
│ new_textfile.txt
│ textfile_shift_jis.txt
│ textfile_utf8 – コピー.txt
│ textfile_utf8.txt
│ todofuken.xls
│ todofuken.xlsx
│ wakayama.xls

├─audio
├─image
│ techgym_01.jpg
│ techgym_02.jpg
│ techgym_03.jpg

└─video
└─mov
M07_008.MOV


Pythonの osモジュールには関数 .walk() があります。

os.walk()は、指定したディレクトリのサブディレクトリまで探索してくれる便利な関数です。

os.walk()にディレクトリのパスを指定すると、

ディレクトリ直下のファイルのリストは勿論、サブディレクトリのリスト、サブディレクトリ下のサブディレクトリのリスト・ファイルのリスト …

と、階層構造のディレクトリを隈なく探索し次の3つの情報を返します。

・現在のディレクトリのパス
・現在のディレクトリの中のサブディレクトリのリスト
・現在のディレクトリ内のファイルのリスト


試しに、os.walk()にディレクトリパスを指定して、どの様な情報が返されるのか確認してみましょう。

for文でos.walk()で取得したリストを、

[current_dir](現在のディレクトリのパス)
[sub_dirs](現在のディレクトリの中のサブディレクトリのリスト)
[files_list](現在のディレクトリ内のファイルのリスト)

に振り分け、printで出力します。

import os

dir_path = "D:/liquidjumper"




for current_dir, sub_dirs, files_list in os.walk(dir_path):
    print(u"現在のディレクトリは {} です".format(current_dir))
    print(u"サブディレクトリは {} です".format(sub_dirs))
    print(u"ディレクトリ内のファイルは {} です".format(files_list))
    print("//////////////////////////////////////////////")


実行:

各階層のディレクトリ、サブディレクトリのリスト、ファイルのリストが出力されているのが確認できます。

現在のディレクトリは D:/liquidjumper です
サブディレクトリは [‘audio’, ‘image’, ‘video’] です
ディレクトリ内のファイルは [‘etixAutoSalon.pdf’, ‘new_textfile.txt’, ‘textfile_shift_jis.txt’, ‘textfile_utf8 – \x83R\x83s\x81[.txt’, ‘textfile_utf8.txt’, ‘todofuken.xls’, ‘todofuken.xlsx’, ‘wakayama.xls’] です
//////////////////////////////////////////////
現在のディレクトリは D:/liquidjumper\audio です
サブディレクトリは [] です
ディレクトリ内のファイルは [] です
//////////////////////////////////////////////
現在のディレクトリは D:/liquidjumper\image です
サブディレクトリは [] です
ディレクトリ内のファイルは [‘techgym_01.jpg’, ‘techgym_02.jpg’, ‘techgym_03.jpg’] です
//////////////////////////////////////////////
現在のディレクトリは D:/liquidjumper\video です
サブディレクトリは [‘mov’] です
ディレクトリ内のファイルは [] です
//////////////////////////////////////////////
現在のディレクトリは D:/liquidjumper\video\mov です
サブディレクトリは [] です
ディレクトリ内のファイルは [‘M07_008.MOV’] です
//////////////////////////////////////////////



では、os.walk()を使って、ディレクトリ内のサブディレクトリを含めた、全ファイルの合計サイズを取得してみたいと思います。

os.walk()で取得した3つの情報から、各階層ディレクトリのファイルのリストをfor文で取り出し、os.path.join()でフルパスに変換、os.path.getsize()でファイルサイズを取得。合計値を取得します。

import os

dir_path = "D:/liquidjumper" 

full_size = 0 

for current_dir, sub_dirs, files_list in os.walk(dir_path): 

  for file_name in files_list: 
    file_size = os.path.getsize(os.path.join(current_dir,file_name)) 
    full_size += file_size 

print(full_size)


実行:

指定したディレクトリ”D:/liquidjumper”内のサブディレクトリを含む、全てのファイルの合計サイズを取得することができました。

4727460


まとめ

Pythonで指定したディレクトリ内にある全ファイルの合計サイズを取得する方法を解説しました。

Pythonでファイルのサイズを取得するのは簡単ですが、ディレクトリ内のファイルをサイズを取得する場合は、すこし工夫やテクニックが必要になることが分かります。

知ってしまえば難しい事では無いので、機会があれば是非参考にしてみてください。

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

■ディレクトリ内の全ファイルのサイズを取得

os.listdir()又は、os.scandir()でディレクトリ内のリストを取得し、os.path.getsize()でファイルサイズを取得

■ファイルの拡張子を限定してファイルの合計サイズを取得

glob.glob()にワイルドカードを追記したディレクトリパスを指定、ワイルドカードで限定した拡張子のみリストを取得し、os.path.getsize()でファイルサイズを取得

■サブディレクトリのファイルも含めた合計サイズを取得

os.walk()にディレクトリパスを指定、3つの情報を取得。各階層ディレクトリのリストから、os.path.getsize()でファイルサイズを取得







【TechAcademy(テックアカデミー)ブートキャンプ】

TechAcademy [テックアカデミー] では、初心者でも短期間でPython・機械学習が学べるオンラインブートキャンプPythonコース を開催しています。

過去に独学のプログラミング学習で挫折した経験のある方でも、パーソナルメンターがビデオとチャットでサポート。疑問点を直ぐに解決して次の課題に取り組めます。

オンラインプログラミングスクール受講者No.1、TechAcademy(テックアカデミー)の学習システムの内容や疑問点を聞く事ができるTechAcademy無料動画説明会 も実施されているので、ぜひ参加してみてください。



Twitter Facebook Pocket LINE はてブ

おすすめの関連記事
コチラの記事も読まれています
あわせてよく読まれている記事