Arhn - архитектура программирования

LINQ-перечисление локальных каталогов с использованием DriveInfo

Я знаю, что есть много способов выполнить то, что я пытаюсь сделать здесь, но я хотел попробовать это с помощью 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, установленным на «Устройство не готово».

Я не понимаю, почему это происходит, потому что у меня есть тест localDrive.IsReady в запросе LINQ, или, по крайней мере, я так думаю.

18.05.2011

  • Марк ответил на настоящий вопрос, поэтому два комментария обзора кода: этот код фактически выполняет запрос дважды, один раз для подсчета и еще раз для поиска первого элемента. Вам также не нужно использовать ToString для строки. Все после построения запроса можно заменить на string path = bestAPIDataDrives.FirstOrDefault() ?? systemDrive. Вам также не нужно создавать список из результатов DriveInfo.GetDrives(), а можно сказать IEnumerable<DriveInfo> localDrives = DriveInfo.GetDrives(). 18.05.2011
  • @Chris - хорошее место; Я определенно согласен - здесь следует использовать FirstOrDefault() (и ничего больше; это охватывает как Count(), так и ElementAt(), гораздо эффективнее) 18.05.2011
  • Всем еще раз хороший совет. Большое спасибо. Обновит решение с помощью этих элементов проверки кода. 18.05.2011

Ответы:


1

это 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;

Запуск сортировки после фильтров в любом случае является хорошей идеей, так как вы снижаете стоимость сортировки (которая всегда суперлинейна).

Как отмечает Крис, вы просто хотите закончить:

string path = bestAPIDataDrives.FirstOrDefault() ?? systemDrive;
18.05.2011
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..