2012-06-26 8 views
7

私は、ユーザーがカウントの進行状況を見ることができるように負荷を分割する方法でディレクトリサイズを計算しようとしています。私はこれを行う論理的な方法は、最初にディレクトリツリーを作成し、すべてのファイルの長さを数える操作を行うことだと思った。ディレクトリのサイズを計算する

予想外のこととして、ディレクトリツリーの作成から大量の時間(ディスクI/O)が発生し、実質的にディスクI/Oがなくなり、FileInfo[]をほぼ瞬時に処理できます。

私はDirectory.GetDirectories()でディレクトリ名の文字列ツリーを作成し、DirectoryInfoオブジェクトを使用してみましたが、どちらの方法もI/O時間の大部分を占めています(もちろんMFTを読む)各ディレクトリ内のファイルについてすべてFileInfo.Lengthを参照してください。

ツリーを大きくするためにI/Oを減らす方法はないと思うが、私はこの操作がより多くのファイルを調べるのに比べてかなり長い時間を要すると思うだろうか?

また、誰かが再帰的なやり方で物事を集計することを勧めてもいいです(私はちょうど列挙を分割し、サイズをもっと反応的にするためにバランスをとる必要があるからです)。サブディレクトリごとにスレッドをベースから外して、スケジューラの競合のバランスを取ることはおそらくあまり良くないでしょうか?

EDIT:Repository for this code

+0

私はディレクトリサイズの計算にも苦労しました。私はあなたがしたことを正確に行った。 > fileInfo []を試してから、Directory.GetDirectories()を試してみてください。しかし、私はまだもっと良い方法を知らない。 –

+0

GetDirectories()を呼び出すのに時間がかかると言っていますか?私はそれを見たことはありませんが、もう一度、私は大量のディレクトリでこれをやったことはありません。また、なぜその再帰的な場合あなたは気になるでしょうか?これは再帰的な作業であり、ネストされたディレクトリは決して爆発することはありません。 –

+0

を参照してください。http://stackoverflow.com/questions/468119/whats-the-best-way-to-calculate-the-size-of-a-directory-in-net –

答えて

4

あなたが並列にディレクトリサイズの計算を実行するためにParallel.ForEachを利用することができます。各ノードでGetDirectoriesを取得し、Parallel.ForEachを実行することができます。変数を使用すると、サイズを追跡してユーザーに表示することができます。各並列計算は、同じ変数に対してインクリメントします。必要に応じて、lock()を使用して並列実行を同期させます。

+0

関連性のないディレクトリだけが並列化され、それを超えてロックする理由はないように、コード化する必要があります。ほとんどのディスクでは、どの並列化があなたを得るのか分かりません。ディスクIOは本質的に同期しているように見えます。あなたが実際に並行させることができるのは、実際に無視できるはずの総計です。 –

+2

SSDと並行IOを得ることができます。 –

+0

@JasonMalinowski本当に...私には分かりませんでした。ほとんどのOSはそれをどのように活用するのか知っていますか?私はそれがずっと動いている部分のビットのためにはるかに速かったことを知っていた、それも平行して有効になっていることを知らなかった。 –

関連する問題