ディレクトリサイズ一覧の取得方法あれこれ

自分の知っている範囲で、ディレクトリサイズの一覧取得方法を整理しました。対象とするファイル属性(隠し)やハードリンクを追うかどうか等の問題か、ツールで微妙に値が異なる場合があります。エクスプローラのフォルダのプロパティの全般タブと表示内容が近いのは「sdu」か「素のPowerShell」でしょうか。

コマンドプロンプト

du(sysinternals)

MicrosoftはIT担当者や開発者向けに、Sysinternals というツール群を提供しています。この中の一つにDisk Usage というものがあり、指定したディレクトリの使用状況を取得できます。他のツールと似た結果を得るには、階層の指定、ハードリンクの追跡、バナーの非表示を指定します。

C:\>du -l 1 -u c:\Windows\Microsoft.NET -nobanner
     198,774  c:\windows\microsoft.net\assembly
           0  c:\windows\microsoft.net\authman
      29,154  c:\windows\microsoft.net\DirectX for Managed Code
     295,576  c:\windows\microsoft.net\Framework
     324,718  c:\windows\microsoft.net\Framework64
Files:        3589
Directories:  1459
Size:         868,580,329 bytes
Size on disk: 885,002,240 bytes

sdu

動作OSにWin95やNT(3.51か4.0と思われる)があるいにしえのツールですが、Win10でも問題なく使えます。圧縮形式がlhaなので、解凍には7-zipなどのアーカイバが必要。フォルダ名の欄が固定サイズなので、長いフォルダ名だと表示が崩れてしまうのが悩みどころ。

C:\>sdu c:\Windows\Microsoft.NET
directory name                           size(MB)       % dirs  files
---------------------------------------------------------------------
c:\Windows\Microsoft.NET\assembly         195.555 ( 23.4) 1256    717
c:\Windows\Microsoft.NET\authman            0.000 (  0.0)    0      0
c:\Windows\Microsoft.NET\DirectX for Managed Code   28.516 (  3.4)   10     36
c:\Windows\Microsoft.NET\Framework        291.426 ( 34.9)   97   1427
c:\Windows\Microsoft.NET\Framework64      319.926 ( 38.3)   90   1411
c:\Windows\Microsoft.NET                    0.000 (  0.0)    5      0
---------------------------------------------------------------------
Total                                     835.422         1458   3591

PowerShell

素のPowerShell

PowerShellでは、Get-ChildItemで取得できるFileSystemInfoオブジェクトにLength(サイズ)プロパティがあるので、それを再帰的に合計することで、ディレクトリごとのサイズ一覧を取得可能です。

(Get-ChildItem -Force $_.FullName -Recurse|Measure-Object -Property Length -Sum).Sum

関数化したものをこちらで公開しています。FileSystemObjectを使わないことをオプションで指定しています。

PS C:\> Get-DirectorySize C:\Windows\Microsoft.NET\ -NonFso

Name                     Size      SizeByte Files Folders
----                     ----      -------- ----- -------
assembly                   194.1M 203544778   717    1256
authman                      0.0B               0       0
DirectX for Managed Code    28.5M  29853934    36      10
Framework                  288.6M 302670920  1427      97
Framework64                317.1M 332509797  1411      90

FileSystemObjectを使う

再帰で取得するのはパフォーマンスが微妙なのではないかとの懸念から、FileSystemObjectを使用するバージョンを作成しました。PowerShell(マネージドコード?)から、COMを呼び出すと実行権限が委譲できないのか、特殊フォルダなどでアクセス権のエラーが発生することがありますが、素のPowerShellよりは早いです。関数化したこちらのデフォルト動作です。

$fso = New-Object -ComObject Scripting.FileSystemObject 
$fso.GetFolder($_.FullName).size
PS C:\> Get-DirectorySize C:\Windows\Microsoft.NET\

Name                     Size      SizeByte Files Folders
----                     ----      -------- ----- -------
assembly                   194.1M 203544778   717    1256
authman                      0.0B         0     0       0
DirectX for Managed Code    28.5M  29853934    36      10
Framework                  288.6M 302670920  1427      97
Framework64                317.1M 332509797  1411      90

モジュール「PSFolderSize」を使う

Microsoftが「PowerShell コンテンツの中央リポジトリ」と言っているPowerShell ギャラリーに「PSFolderSize」があります。インターネット接続環境かつインストール可能であれば、これが手っ取り早いかもしれません。

PS C:\> Get-FolderSize C:\Windows\Microsoft.NET\

FolderName                     SizeMB       SizeGB       FullPath
----------                     ------       ------       --------
Framework64                    317.11       0.31         C:\Windows\Microsoft.NET\Framework64
Framework                      288.65       0.28         C:\Windows\Microsoft.NET\Framework
assembly                       194.12       0.19         C:\Windows\Microsoft.NET\assembly
DirectX for Managed Code       28.47        0.03         C:\Windows\Microsoft.NET\DirectX for Managed Code
authman                                                  C:\Windows\Microsoft.NET\authman

実行時間比較

ローカルHDD(SATA)の約40GBのフォルダのサイズ一覧の取得にかかった時間は次のとおりでした。測定はMeasure-Commandで行いました。実行のたびに10msの桁は変わるので、有効桁は1桁な気もしますが、とりあえず2桁で整理。

ツール 実行時間[ミリ秒]
du 430
sdu 74
素のPowerShell関数 860
PowerShellからFileSystemObject 590
PSFolderSize 390

ライセンス

どのツールも使用上の費用発生はありません。Sysinternals は商用ホスティング サービスでの使用が禁止されていますのでご注意ください。詳細はリンク先を参照のこと。

ツール ライセンス
du Sysinternals ソフトウェアライセンス条項
sdu フリーソフト(付属テキスト「SDU.TXT」を参照)
PSFolderSize MIT

参考サイト