特定のフォルダーがディスク上でどれくらいの容量を占めているか、正確に知りたい場面はよくあります。
Windows のエクスプローラーでプロパティを開く方法もありますが、スクリプトで自動的にサイズを取得できると、バックアップの要否を判断したり、ディスクの空き容量を監視したりと、様々な応用が可能です。
今回は、AutoIt を使って指定したフォルダーの合計サイズ(サブフォルダーの中身もすべて含む)を計算し、分かりやすい単位で表示する方法を解説します。
完成したスクリプトの全コード
#include <File.au3>
#include <MsgBoxConstants.au3>
; ### メイン処理 ###
; 1. ユーザーにサイズを計算したいフォルダーを選択させる
Local $sFolderPath = FileSelectFolder("合計サイズを計算したいフォルダーを選択してください。", "")
If @error Then Exit
MsgBox($MB_OK, "計算開始", "OK をクリックするとフォルダーのサイズを計算します。フォルダーの大きさによっては時間がかかる場合があります。")
; 2. 指定フォルダー内の全ファイルリストを再帰的に取得
Local $aFileList = _FileListToArrayRec($sFolderPath, "*", $FLTAR_FILES, $FLTAR_RECUR, 0, 2)
If @error Then
MsgBox($MB_ICONINFORMATION, "情報", "フォルダー内にファイルが見つからないか、フォルダーが空です。")
Exit
EndIf
; 3. 合計サイズを計算するループ
Local $iTotalSize = 0 ; 最初は0で初期化
For $i = 1 To $aFileList[0]
; ファイルのサイズをバイト単位で返します
$iTotalSize += FileGetSize($aFileList[$i])
Next
; 4. 計算結果を分かりやすい単位に変換して表示
Local $sFormattedSize = _FormatBytes($iTotalSize)
MsgBox($MB_OK, "計算完了", "選択されたフォルダーの合計サイズ:" & @CRLF & @CRLF & $sFormattedSize)
Exit
; ### バイト数を適切な単位(KB, MB, GB)の文字列に変換する関数 ###
Func _FormatBytes($iBytes)
If $iBytes = 0 Then Return "0 Bytes"
Local $aUnits[4] = ["Bytes", "KB", "MB", "GB"]
Local $iUnitIndex = 0
While $iBytes >= 1024 And $iUnitIndex < UBound($aUnits) - 1
$iBytes = $iBytes / 1024
$iUnitIndex += 1
WEnd
Return StringFormat("%.2f", $iBytes) & " " & $aUnits[$iUnitIndex]
EndFunc ;==>_FormatBytes
コードの詳しい解説
全ファイルのリストアップ
このスクリプトは、まず計算対象となるファイルをすべてリストアップすることから始まります。
_FileListToArrayRec: この関数が、指定されたフォルダーとその中にある全てのサブフォルダーを再帰的に検索し、ファイルだけのリストを配列として取得します。第 6引数に2を指定することで、リストに含まれるパスが常にフルパス(絶対パス)になるようにしています。
合計サイズの計算
次に、取得したファイルリストを使って合計サイズを計算します。
Forループ:Forループを使い、ファイルリストのファイルを一つずつ取り出します。FileGetSize: ループの中でFileGetSize関数を呼び出し、各ファイルのサイズをバイト単位で取得します。- 通常の 32ビット整数では、約 2GBまでの数値しか扱えません。しかし、
FileGetSize関数は、この 2GB の壁を超える巨大なファイルのサイズも正しく取得できるように設計されています。 - AutoIt の変数は非常に柔軟で、中に入れられた値に応じて自動的に型が変わります。最初に
$iTotalSizeを0で初期化しても、ループの中でFileGetSizeが返した巨大な数値が加算されると、AutoIt はオーバーフロー(桁あふれ)を防ぐために自動的に$iTotalSize変数を 64ビット整数として扱えるように拡張します。
バイトを分かりやすく変換
計算された合計サイズは、非常に大きなバイト数の数値になっています。これを人間が読みやすい単位に変換するのが_FormatBytesという自作関数です。
- 単位の定義:
KB,MB,GBといった単位を配列で用意しておきます。 Whileループ: 元のバイト数が 1024以上である限り、1024 で割り算を繰り返します。割り算を 1回するごとに、単位をBytes→KB、KB→MBと格上げしていきます。StringFormat: 最終的に計算された数値を、StringFormatを使って小数点以下2桁に整形します。- 戻り値: 整形した数値と、最終的に決まった単位の文字列を連結して返します。(例:
15.23 MB)
StringFormat(“%.2f”, $iBytes)
%.2fは、StringFormat関数で使われる書式指定子で、「数値を小数点以下 2桁で表示する浮動小数点数(小数)として整形してください」という意味の命令です。
「%.2f」の分解
この文字列は3つの部分に分解できます。
- % (パーセント記号)これは「ここから書式指定が始まりますよ」という合図の文字です。
- .2 (ドットと数字)これは精度を指定します。小数点数(f)と組み合わせた場合、「小数点以下の桁数を 2桁にしてください」という意味になります。
- 元の数値の小数点以下が 3桁以上ある場合は、四捨五入されます。
- 元の数値の小数点以下が1桁しかない場合は、
0で埋めて 2桁にします。 - 元の数値が整数だった場合は、
.00を付けて 2桁にします。
- f (エフ)これは型を指定します。f は float(浮動小数点数)、つまり小数として扱ってください、という意味です。
具体的な例
StringFormat("%.2f", $iBytes)を実行した場合、$iBytesの中身によって出力は以下のように変わります。
元の数値 ($iBytes) | 出力結果 | 説明 |
12.3456 | "12.35" | 小数点以下3桁目の5が四捨五入されます。 |
98.7 | "98.70" | 2桁に満たないため、末尾が0で埋められます。 |
150 | "150.00" | 整数に.00が追加されます。 |
この%.2fという書式は、ファイルサイズを「1.75 GB」のように、見やすく統一された形式で表示するために非常によく使われます。
まとめ
このスクリプトは、フォルダー内の全ファイルをリストアップし、それぞれのサイズを足し合わせるという確実なアプローチで合計サイズを算出しています。
特に、AutoIt が大きな数値を扱う際に自動的に変数の型を拡張してくれる点は、コードをシンプルに保つ上で非常に便利です。
_FormatBytes 関数も、様々な場面で応用できる便利な部品です。
【アップグレード編】フォルダーサイズ計算ツールに「処理中」画面を追加する
上記のフォルダーサイズ計算ツールは、指定したフォルダーの合計サイズを正確に計算できる便利なものでした。しかし、このシンプルなスクリプトには一つ課題があります。
巨大なフォルダーやネットワーク上のフォルダーを選択すると、計算が終わるまで画面が固まったように見えてしまい、ユーザーは「本当に動いているのだろうか?」と不安になってしまいます。
そこで今回は、このツールをアップグレードし、計算中に「処理中」であることを示すスプラッシュスクリーンを表示する機能を追加します。
さらに、処理の段階に合わせてメッセージを更新することで、より親切なツールに仕上げます。
完成したアップグレード版コード
#include <File.au3>
#include <MsgBoxConstants.au3>
; ### グローバル変数 ###
Global $g_hSplashGUI, $g_idSplashLabel ; スプラッシュスクリーン関連のID
; ### メイン処理 ###
Local $sFolderPath = FileSelectFolder("合計サイズを計算したいフォルダーを選択してください。", "")
If @error Then Exit
; 1. スキャン開始前にスプラッシュスクリーンを表示
_CreateSplash("処理中...", "フォルダーをスキャンしています...")
; 2. 指定フォルダー内の全ファイルリストを再帰的に取得
Local $aFileList = _FileListToArrayRec($sFolderPath, "*", $FLTAR_FILES, $FLTAR_RECUR, 0, 2)
If @error Then
_CloseSplash()
MsgBox($MB_ICONINFORMATION, "情報", "フォルダー内にファイルが見つからないか、フォルダーが空です。")
Exit
EndIf
; 3. メッセージを「計算中」に更新
_UpdateSplashText("合計サイズを計算しています...")
; 4. 合計サイズを計算するループ
Local $iTotalSize = 0
For $i = 1 To $aFileList[0]
$iTotalSize += FileGetSize($aFileList[$i])
Next
; 5. 計算完了後にスプラッシュスクリーンを閉じる
_CloseSplash()
; 6. 計算結果を分かりやすい単位に変換して表示
Local $sFormattedSize = _FormatBytes($iTotalSize)
MsgBox($MB_OK, "計算完了", "選択されたフォルダーの合計サイズ:" & @CRLF & @CRLF & $sFormattedSize)
Exit
; ### バイト数を適切な単位(KB, MB, GB)の文字列に変換する関数 ###
Func _FormatBytes($iBytes)
If $iBytes = 0 Then Return "0 Bytes"
Local $aUnits[4] = ["Bytes", "KB", "MB", "GB"]
Local $iUnitIndex = 0
While $iBytes >= 1024 And $iUnitIndex < UBound($aUnits) - 1
$iBytes = $iBytes / 1024
$iUnitIndex += 1
WEnd
Return StringFormat("%.2f", $iBytes) & " " & $aUnits[$iUnitIndex]
EndFunc ;==>_FormatBytes
; ### 計算中スプラッシュスクリーン用の関数 ###
Func _CreateSplash($sTitle, $sText)
$g_hSplashGUI = GUICreate($sTitle, 300, 100, -1, -1, -1, 0x00000010)
$g_idSplashLabel = GUICtrlCreateLabel($sText, 10, 20, 280, 50, 0x01)
GUISetState(@SW_SHOW, $g_hSplashGUI)
EndFunc
Func _UpdateSplashText($sText)
GUICtrlSetData($g_idSplashLabel, $sText)
EndFunc
Func _CloseSplash()
GUIDelete($g_hSplashGUI)
EndFunc
アップグレード内容の詳しい解説
スプラッシュスクリーン用の関数群
今回のアップグレードの核となる、3つの新しいヘルパー関数を追加しました。
_CreateSplash: 「処理中」メッセージを表示するための、ボタンなどがないシンプルなウィンドウを作成します。_UpdateSplashText: 表示されているメッセージを、新しいテキストに更新します。_CloseSplash: 表示されているスプラッシュスクリーンを閉じます。
これらの関数で使うウィンドウやラベルの ID は、他の関数からもアクセスできるようにグローバル変数($g_hSplashGUI, $g_idSplashLabel)として定義しています。
メイン処理への組み込み
メインの処理フローの中に、これらの関数を適切なタイミングで呼び出すように組み込みました。
_CreateSplash("...スキャンしています..."): 時間のかかる可能性のある_FileListToArrayRecが始まる前に、まず「スキャン中」のメッセージを表示します。_UpdateSplashText("...計算しています..."): スキャンが終わり、次に時間のかかる合計サイズの計算ループが始まる前に、メッセージを「計算中」に更新します。_CloseSplash(): 全ての重い処理が終わった後、最終的な結果をMsgBoxで表示する直前に、スプラッシュスクリーンを閉じます。
まとめ
このスプラッシュスクリーンを追加するだけで、スクリプトの体感的なパフォーマンスと信頼性が大きく向上します。処理に時間がかかる場合でも、ユーザーは「今、何が行われているか」を把握できるため、安心して待つことができます。
単純な自動化スクリプトから、対話的で親切な「アプリケーション」へと進化させる上で、このようなユーザーへの配慮は非常に重要なステップです。
コメント