3

ここでやろうとしていることを達成するには多くの方法があることはわかっていますが、LINQ で試してみたかったのですが、(私にとって) 奇妙な結果がいくつか見られます。ここで誰かが私に提供する知恵を持っていることを願っています。

目標は、可能であれば %SystemDrive% ボリュームを除いて、NTFS ファイル システムにフォーマットされた最も利用可能な空き領域で実行するローカル マシン上のドライブを見つけることです。もう 1 つの注意点は、ボリューム文字が割り当てられているが、まだフォーマットされていないドライブは、候補プールから除外する必要があるということです。これは特殊なケースですが、1 人のお客様が既にこの問題に遭遇しています。

だから、私はしようとしています:

string systemDrive = Environment.GetEnvironmentVariable("SystemDrive") + "\\";

List<DriveInfo> localDrives = DriveInfo.GetDrives().ToList();

var bestAPIDataDrives = from localDrive in localDrives
            orderby localDrive.AvailableFreeSpace descending
            where   localDrive.DriveType == DriveType.Fixed &&
                    localDrive.DriveFormat == "NTFS" &&
                    localDrive.RootDirectory.FullName != systemDrive &&
                    localDrive.IsReady
            select  localDrive.RootDirectory.FullName;

string path = String.Empty;

if (bestAPIDataDrives.Count() == 0)
{
    // there is only a system drive available, use it anyway.
    path = systemDrive;
}
else
{
    path = bestAPIDataDrives.ElementAt(0).ToString();
}

bestAPIDataDrives.Count() 参照に到達すると、Message プロパティが「デバイスの準備ができていません」に設定された IOException を取得します。

LINQ クエリに localDrive.IsReady テストがあるため、または少なくともそう思うので、なぜこれが起こっているのかわかりません。

4

1 に答える 1

4

これは LINQ-to-Objects であるため、提示された順序で操作が実行されます。特に、フィルタリングする前に並べ替えを試み、ほとんどすべてのフィルターがキーIsReadyテストの前に実行されます。私は単にそれらを再注文します:

var bestAPIDataDrives = from localDrive in localDrives
            where   localDrive.IsReady &&
                    localDrive.DriveType == DriveType.Fixed &&
                    localDrive.DriveFormat == "NTFS" &&
                    localDrive.RootDirectory.FullName != systemDrive     
            orderby localDrive.AvailableFreeSpace descending                   
            select  localDrive.RootDirectory.FullName;

フィルターの後に並べ替えを実行することは、並べ替えのコストを削減するため、とにかく良い考えです (これは常に超線形です)。

Chris が指摘しているように、次のように仕上げます。

string path = bestAPIDataDrives.FirstOrDefault() ?? systemDrive;
于 2011-05-18T12:13:56.810 に答える