• 締切済み

フォルダのサイズを取得したい

WindowsXP+VB6.0を使用して、特定フォルダ内のサイズを取得したいのです。FileSystemObjectのFolderオブジェクトのSizeプロパティでは 特定フォルダのプロパティのサイズの値となってしまいます。 取得したいのは「ディスク上のサイズ」の値です。 宜しくお願い致します。

みんなの回答

回答No.6

動作確認用に入れた下記処理が残っていました。削除しといてください。 List1.AddItem CStr(RoundUp(MergeDWORD(lngFileSizeHigh, lngFileSizeLow), lngClusterSize)) & " " & strFolderName & "\" & fil.Name

回答No.5

ちょっとサンプルを作ってみました。実際に使うには、いろんな環境で確認してから使ってください。  使用方法は、getFolderSize("c:\temp")のようにパス名を指定して関数を呼んでください。結果は、2GB以上でもOKなようにCurrency型で返ります。  尚、WindowsのAPIの定義は、APIビューワからコピーしてください。 ' 指定したフォルダのディスク上のサイズを求める Function getFolderSize(strFolderName As String) As Currency Dim udtVersionInfo As OSVERSIONINFO ' OSのバージョン取得用 Dim fso As FileSystemObject ' FileSystemObject のハンドル Dim fldr As Folder ' フォルダオブジェクトのハンドル Dim sfldr As Folder ' サブフォルダのオブジェクトのハンドル Dim fil As File ' ファイルオブジェクトのハンドル Dim curSum As Currency ' ファイルサイズの合計 Dim lngFileSizeHigh As Long ' ファイルサイズの上位 DWORD Dim lngFileSizeLow As Long ' ファイルサイズの下位 DWORD Dim lngReturnValue As Long ' 戻り値 Dim lngSectorsPerCluster As Long ' セクタ数/クラスタ Dim lngBytesPerSector As Long ' バイト数/セクタ Dim lngNumberOfFreeClusters As Long ' 空きクラスタ数 Dim lngTotalNumberOfClusters As Long ' 全クラスタ数 Dim lngClusterSize As Long ' クラスタサイズ ' 合計をクリア curSum = 0 ' OSのプラットフォームを調べる udtVersionInfo.dwOSVersionInfoSize = Len(udtVersionInfo) lngReturnValue = GetVersionEx(udtVersionInfo) ' ドライブのクラスタサイズを調べる lngReturnValue = GetDiskFreeSpace(Left(strFolderName, 3), lngSectorsPerCluster, lngBytesPerSector, lngNumberOfFreeClusters, lngTotalNumberOfClusters) lngClusterSize = lngSectorsPerCluster * lngBytesPerSector ' FileSystemObject オブジェクトの作成 Set fso = New FileSystemObject ' フォルダオブジェクトのハンドルを取得 Set fldr = fso.GetFolder(strFolderName) ' サブフォルダを列挙し、再帰的に呼び出す For Each sfldr In fldr.SubFolders curSum = curSum + getFolderSize(sfldr.Path) Next sfldr ' ファイルを列挙し、ディスク上のファイルサイズを求める For Each fil In fldr.Files If udtVersionInfo.dwPlatformId = "1" Then ' 95系OS curSum = curSum + RoundUp(fil.Size, lngClusterSize) Else If Right(strFolderName, 1) = "\" Then lngFileSizeLow = GetCompressedFileSize(strFolderName & fil.Name, lngFileSizeHigh) Else lngFileSizeLow = GetCompressedFileSize(strFolderName & "\" & fil.Name, lngFileSizeHigh) End If curSum = curSum + RoundUp(MergeDWORD(lngFileSizeHigh, lngFileSizeLow), lngClusterSize) List1.AddItem CStr(RoundUp(MergeDWORD(lngFileSizeHigh, lngFileSizeLow), lngClusterSize)) & " " & strFolderName & "\" & fil.Name End If Next fil ' オブジェクトの解放 Set fil = Nothing Set sfldr = Nothing Set fldr = Nothing Set fso = Nothing ' 合計を戻り値にセット getFolderSize = curSum End Function ' 2つのDWORDに分割された値をCurrency型に変換 Function MergeDWORD(lngFileSizeHigh As Long, lngFileSizeLow As Long) As Currency If (lngFileSizeLow And &H80000000) = &H80000000 Then MergeDWORD = CCur(lngFileSizeHigh) * 4294967296@ _ + 2147483648@ + CCur(lngFileSizeLow) Else MergeDWORD = CCur(lngFileSizeHigh) * 4294967296@ _ + CCur(lngFileSizeLow) End If End Function ' クラスタサイズの倍数に切り上げる Function RoundUp(curFileSize As Currency, lngClusterSize As Long) As Currency Dim curMod As Currency ' 余り curMod = curFileSize Mod lngClusterSize If curMod <> 0 Then RoundUp = curFileSize + (lngClusterSize - curMod) Else RoundUp = curFileSize End If End Function GetDiskFreeSpace関数について ・Windows 95(OSR2以前)では、正しい値を返しません。 ・将来的に使えなくなる場合があります。(Vistaは、OK) 詳しくは、下記を参照 http://msdn.microsoft.com/ja-jp/library/cc429305.aspx GetCompressedFileSize関数について ・ファイルを圧縮している場合は、GetCompressedFileSize関数を使う必要があります。 ・ファイルサイズがクラスタサイズより小さいと、もとのファイルサイズのままなのでクラスタサイズに切り上げる処理を入れてます。 ・95系のOSではサポートしていないので、バージョンのチェックを入れています。

  • argument
  • ベストアンサー率63% (21/33)
回答No.4

こんばんわ takao0429 さん はい。まぁそれは良いでしょう。実は貴方のために苦心してサンプルソースを考えました。 ・・・。すいません前言をやっぱり訂正します。私の興味本意と前回ちょっと適当にクラスタ算出がうまくいかなかったものがなんだか自分に負けた気がしたので遊びで少しロジックを変更して遊んでいたのです。 そうそう貴方はFileSystemObjectを扱えるんでしたね。なので遊びでできたもののうちFileSystemObjectを使って算出するソース張りましょう。あぁ大切な事を言うのを忘れていました。 今からはるソースはVBのソースではなくVBSのソースです。なぜって? テキストエディタなら何処にでもあるのでいい暇つぶしができるからです。 今から貼るソースをテキストエディタを開いて「test.vbs」と名前をつけて保存してください。 "c:\work"の部分は貴方の好きなフォルダを指定してください。 clustersize は標準値です。貴方のPCのクラスタサイズを私は知りません。 [test.vbs] treeroot = "c:\work": patharray = Array(treeroot): clustersize = 4096: Set fso = CreateObject("Scripting.FileSystemObject") For Each fl In fso.GetFolder(treeroot).Files If fl.Size Mod clustersize Then diskfoldersize = diskfoldersize + (Fix(fl.Size / clustersize) * clustersize + clustersize) Else diskfoldersize = diskfoldersize + fl.Size Next Do While 1 temp = "": ReDim patharray2(UBound(patharray)): For i = 0 To UBound(patharray) Set gf = fso.GetFolder(patharray(i)): fn = "": For Each fl In gf.subfolders: fn = fn & fl.Name & "\": Next: If InStr(fn, "\") > 0 Then patharray2(i) = Split(Left(fn, Len(fn) - 1), "\") Else patharray2(i) = Array("") For j = 0 To UBound(patharray2(i)) If patharray2(i)(j) = "" Then Exit For temp = temp & patharray(i) & "\" & patharray2(i)(j) & "/": For Each fl In fso.GetFolder(patharray(i) & "\" & patharray2(i)(j)).Files If fl.Size Mod clustersize Then diskfoldersize = diskfoldersize + (Fix(fl.Size / clustersize) * clustersize + clustersize) Else diskfoldersize = diskfoldersize + fl.Size Next: Next: Next: If temp = "" Then Exit Do Else patharray = Split(Left(temp, Len(temp) - 1), "/") Loop MsgBox diskfoldersize さてどうでしょうか?実行してみましたか? そのフォルダを右クリックしてディスク上のサイズと比較してください。同じ値になっている事でしょう。 オーバーフローした?ならきっと2GBを超えるフォルダを指定したんでしょうね。 あぁ…それにしても見づらい。何が書いてあるかわかりません。 貴方の為に書いたとやっぱり言えませんね。最初に言いましたがこれは遊びでできたものです。これは「FileSystemObjectを使ってもディスク上のサイズを取得できます」というためのサンプルでありそれ以上の価値はありません。もちろん貴方がこれを改変してVBソースに直してもよいでしょう(私は気にしません)。 ただ遊びじゃないのならsubをつくりGetFolderオブジェクトを渡すような再帰的処理にしたほうが綺麗なソースになりますね(CPUは食うかもしれませんが)。 1番さんの補足となりますが私が覚えている限りGetDiskFreeSpaceは2GBを超えると信用性のある値が返らなかったと思いますが…。 まぁ恐らくFAT32あたりの関係でしょうね(知識からの推測ですので間違いかもしれませんが)。 あまぁそもそもGetDiskFreeSpaceExができたせいでGetDiskFreeSpaceはいつ廃止またはサポートされるなくなるかわからないものだったと思います。

回答No.3

圧縮ファイルを使用している場合は、GetCompressedFileSize関数と クラスタサイズに切り上げる方法の両方に対応する必要がありそう ですね。 ちなみに、クラスタサイズは、GetDiskFreeSpace関数を使えば 計算することができます。

  • argument
  • ベストアンサー率63% (21/33)
回答No.2

こんばんわ takao0429 さん まずファイルサイズとディスク上のサイズこれはなんだかわかりますか? この差の事をクラスタギャップといいます。 そしてこのクラスタとは書き込みの最小単位です。 通常fsoなどではファイル自体のサイズを返します。きっとfsoを考えた方が面倒だったのでしょう(きっと違うでしょう)。 実際考えると面倒です。まぁでも実際に1番さんの言うとおり計算しましょうか 何が面倒でしょうか?それはクラスタはOSやフォーマット形式などにより1クラスタ数が変動するという点にあります。 3.51よりも前のバージョンの Windows NT では NTFS ファイル圧縮がサポートされていないためクラスタのサイズが大きくなります。たとえば windows95(FAT形式)ならば1クラスタ32KB 1セクタ512Bで64セクタ windowsXP(NTFS形式)ならば1クラスタ4KB 1セクタ512Bで8セクタ となります。 ここまでは分かりましたね?ん?よく分からない? ハードディスクの構造上トラックをセクタで分割していますさらにセクタを分割したのがクラスタです。 そうですね取りあえずOS依存等はマイクロソフトにでも行けば分かります。 http://support.microsoft.com/kb/140365/JA/ さてではどうやって計算しましょうか? まぁ仮にXPで普通にNTFS形式なら1クラスタは512x8=4096Bです。 クラスタで分割しあまりがあった場合1クラスタ分の要領を加算します。 ためしに簡単にVBSで作ってみたんですがやはりフォルダ内のファイルすべてを列挙しないとだめな様で結構な誤差が結構でました。 もっと処理を詰めねばならない用です面倒ですね。実感しました。 (まぁ処理を詰めても良いでしょうが)さて困りました。まぁ待ってください。之を算出してるのwindowsです。ここで思い至ります。win32APIなんか処理ないのかな・・と。 GetCompressedFileSize http://msdn.microsoft.com/ja-jp/library/cc429287.aspx 指定されたファイルがディスク上で実際に占有しているサイズをバイト単位で取得します。ファイルを格納しているボリュームが圧縮機能をサポートしていて、ファイルが圧縮されている場合、圧縮済みのサイズを取得します。 なんだありました。では之で問題解決ですね。 貴方は小難しいクラスタ計算をするかwin32APIを扱えるソースを記述すればこの問題は解決します。 貴方の技量がどれほどあるかは分かりません。ですが上記二つのいづれかの方法をとればフォルダのディスク上のサイズを取得するできる事はわかったでしょう(ソースがほしいと言う場合はこの議題とはまた別件でしょう)。

回答No.1

FileSystemObjectのFolderオブジェクトには、ディスク上のサイズを 求めるプロパティはないので、個々のファイルのサイズを調べて クラスタサイズの倍数に切り上げて、その合計を計算する必要が あるのではないかと思います。

関連するQ&A

  • フォルダのサイズ取得

    300Gのディスクをグループ単位のフォルダに分けて使っているのですが 各グループがどのくらいディスクを使用しているか簡単にサイズ容量を取得する 方法はありませんか? 単純にグループ単位で、右クリック>プロパティにてサイズを取得することも 出来ますが、グループが多いので、出来れば1クリック処理(取得)をするような ツールやコマンド等を教えて頂けると助かります。 以上、宜しくお願い致します。

  • VB6でのファイルサイズ取得について

    VB6ではFileSystemObjectでFileオブジェクトを生成して、 Sizeプロパティからファイルサイズ(バイト)を取得出来ますが、 単純にシーケンシャル入力モードで開いたファイルから、 各行を読み込み、その行の文字列のバイト数を都度加算して行けば 最終的なファイルサイズ(バイト)が取得出来ると考えたのですが、 実際同じ値になりません。 例えば、Sizeプロパティでは、35023バイトのファイルが、 文字列のバイト数を「LenB」で都度加算した場合、 Line Input文で38726バイト、Input文では19363バイトになります。 文字列のバイト数を「Len」で都度加算した場合、 Line Input文で19363バイト、Input文では19361バイトになります。 ファイルは単なるテキストデータです。 なぜ差が出るかの原因を御存知の方教えて頂けませんか? また同じ値になる方法はあるのでしょうか? よろしくお願いします。

  • ファイル-概要-コメントの取得

    ファイルを右クリック-プロパティでファイルのプロパティ画面を開くと、「概要」タブに各種情報が表示されます。 ここで、「説明」-「コメント」の部分に表示されている値を取得したいのです。 FileSystemObjectでFileオブジェクトを取得し、プロパティを見てみましたが、それらしいものはありませんでした。 実現方法がありましたらご教授願います。 Win2000 SP4 + VB6.0 SP6

  • フォルダーのサイズ

    フォルダーのサイズをプロパティーで確認すると 「サイズ」と「ディスク上のサイズ」があり、フォルダーによってはかなり違いますが ディスク上のサイズは、実際のサイズと何が違うのでしょうか?

  • 全サブフォルダのファイルの取得

    VB6のFileSystemObjectを使って、サブフォルダの中のファイルを取得したいのです。 For Each ~ Next 文などをつかっていろいろやっているのですが、どうしてもサブフォルダ以降のサブサブフォルダから下が取得できません。 誰か教えてください。

  • フォルダ サイズについて

    フォルダのサイズについて質問です。 マウスをフォルダにかざして出てくるフォルダサイズと フォルダ上で→右クリック→プロパティ で出てくるサイズおよびディスク上のサイズも上記の数値とは、 それぞれ違うし、 数値にして約3倍も食い違うフォルダがあるのですが、 この3っつのサイズって何なのでしょうか?

  • テーブルのサイズを取得したい

    ストアドまたはVB側から任意のテーブルのディスク使用領域を取得したいと 思っています。sp_spaceusedを使用かと思ったのですが、返値が0か1との ことなのでプログラム内で値が取得できずに困っています。 良い方法があったら教えてください。

  • VBでのOEの保存先フォルダ取得について

    VB2010にて、OutlookExpressのデータ抽出方法について教えてください。 各DBXファイルのファイルサイズを出力するプログラムを自作しようと考えております。 その中で、DBXの保存フォルダの取得方法で悩んでいます。 DBXの保存フォルダを検索対象とし、DBXファイルのサイズ取得を行おうと考えています。 その際のDBXの保存フォルダの取得方法についてですが。 (1)OutlookExpressのレジストリ「Store Root」の値を取得する。 (2)VB上でOEを動かし、オプション内の保存先フォルダの内容をコピーし、その値をプログラム上に引用する。 で出来ないかと考えております。 しかし、VBに関しては超初心者のなのでどの様に記述して良いかで悩める日々です。 利用は、複数台のPCを想定しております。(IDがすべて異なる) ご教示頂けますと幸いです。 また、他の方法などがございましたらご紹介頂けますと幸いです。 ローカルディスク上のDBXファイルを全検索することも考えましたが、 複数アカウントを持つPCの場合、必要無いデータまで取得してしまうので難しいと考えております。 お手数お掛け致しますが宜しくお願い致します。

  • サーバ内のフォルダ名と各フォルダのサイズを取得

    VBS初心者ですが、上司に依頼されて、次の目的のVBSを 作成することとなりましたので、皆様の知恵をお貸し下さい。 1、業務サーバー内に50前後のフォルダが存在する。 2、そのサーバ内のフォルダ名とサイズ(MB表示)を取得する。 3、最終的には、取得したフォルダ名とサイズをcsvで出力する。 現在は、月一でサーバー内の各フォルダのプロパティからサイズを取得して、 エクセルで管理をしているのですが、毎月のようにフォルダが10個単位で増減しているため、 作業に取られる時間が馬鹿にならないので、VBSにて一覧取得をできないか と相談されました。 私のスキルでは、各フォルダ毎のファイル名とサイズを取得することは 出来るのですが、出来れば、一度の操作で全部の作業を終わらせたいので、 皆様のお力をお貸し下さい。

  • ファイルフォルダ サイズ・「サイズ」と「ディスク上のサイズ」の差は+?

    ファイルのプロパティーからファイルフォルダーの サイズをチェックすると 「サイズ」と「ディスク上のサイズ」の2種でてきます。 ディスク上の方が大きいですが差異はなんでしょうか。 意味をご教示下さい。

専門家に質問してみよう