3

我知道有很多方法可以完成我在这里尝试做的事情,但我想用 LINQ 尝试它,并且看到了一些奇怪的(对我而言)结果。希望这里有人能给我一些智慧。

目标是在本地机器上找到我们执行的驱动器,该驱动器具有已格式化为 NTFS 文件系统的最多可用空间,如果可能,不包括 %SystemDrive% 卷。另一个需要注意的是,分配了卷号但尚未格式化的驱动器必须从候选池中排除。这是一个边缘案例,但一位客户已经遇到过。

所以,我正在尝试:

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() 参考时,我得到一个 IOException,Message 属性设置为“设备未准备好”。

我不明白为什么会发生这种情况,因为我在 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 回答