2015-04-08 1 views
0

Я просматривал все, и я не могу найти ответы на все, что касается меня конкретно.Как я могу получить массив файлов или количество файлов на основе нескольких условий

Я пытаюсь либо вернуть массив файлов, либо подсчитать файлы в папке, основанной на нескольких условиях.

Что-то похожее на это: how search file with multiple criteria of extension of file

Однако, я не ищу, чтобы поиск на основе только расширения файла, но и имена файлов.

Например:

Если у меня есть следующие файлы в папке:

test1.mp3

test2.avi

test1.jpg


Как я могу искать все файлы, содержащие «1». Хитрость заключается в том, что пользователи могут динамически добавлять условия для проверки в имени файла. Так что это не может быть примерно так: dInfo.GetFilesByExtensions (". Jpg", ".exe", ".gif");

Условия будут добавлены к множеству условий.

Так что если пользователь теперь также ищет файлы, содержащие «1» и «t». Я бы хотел, чтобы он возвращал либо «2» (например, счетчик), либо как массив этих файлов, например, x - это код.

строка [] файлы = х

после выполнения кода, массив файлов будет выглядеть следующим образом:

файлы [0] = "C: \ test1.mp3"; файлов [1] = "C: \ test1.jpg";

+0

Посмотрите здесь https://msdn.microsoft.com/en-us /library/dd383458(v=vs.110).aspx в примере внизу для запроса linq, который показывает, как искать файлы, содержащие слово «europe». – failedprogramming

+0

Хмм, но мне нужно было сделать что-то вроде этого: string [] условия = {"a", "b"}; foreach (string val in conditions) { var files = из файла в Directory.EnumerateFiles (@ "C: \ library \") где file.ToLower(). Содержит (val) файл выбора; foreach (файл var в файлах) { Console.WriteLine ("{0}", file); } } Куда я бы перебирал свои условия и снова просматривал папку. Я думаю, что это может сработать, но кажется, что это будет немного медленнее. – Faker

+0

Одна из возможных проблем с Directory.EnumerateFiles заключается в том, что вы будете искать весь путь к файлу, а не только имя файла. Поэтому, если вы хотите, чтобы все файлы с '' t'' в них, а путь к файлу содержит '' t'', тогда он вернет все файлы ... –

ответ

1

Вы могли бы сделать некоторые версии следующим:

var folderToSearch = "d:\\public"; 
var nameContains = "1"; 

var filesMeetingCriteria = new DirectoryInfo(folderToSearch) 
    .GetFiles() 
    .Where(file => file.Name.Contains(nameContains)); 

Или использовать список условий, где имя файла должно содержать все условия (но не в любом определенном порядке):

var folderToSearch = "d:\\public"; 
var nameConditions = new List<string> {"r", "t"}; 

var filesMeetingCriteria = 
    new DirectoryInfo(folderToSearch) 
     .GetFiles() 
     .Where(file => 
      nameConditions.All(condition => 
       file.Name.IndexOf(condition) > -1)) 
     .ToList(); 

// To verify the results: 
filesMeetingCriteria.ForEach(file => Console.WriteLine(file.Name)); 

И вы можете сделать без учета регистра сравнения с использованием:

var filesMeetingCriteria = 
    new DirectoryInfo(folderToSearch) 
     .GetFiles() 
     .Where(file => 
      nameConditions.All(condition => 
       file.Name.IndexOf(condition, 
        StringComparison.OrdinalIgnoreCase) > -1)) 
     .ToList(); 
0

Там нет волшебного способа сделать это. Лучшее, что я могу придумать, это настроить фильтры для критериев поиска и использовать linq для фильтрации.

Сначала получите список всех файлов в папке var files = Directory.GetFiles(folder); Это также имеет метод расширения, где вы можете подстановочные как var files = Directory.GetFiles(folder, "*.exe"); Теперь с вашими фильтрами в виде, это может быть перечислением для конкретного действия и строки поиска. Конкретные действия; содержит, начинается с, заканчивается ...

var files = Directory.GetFiles(folder).Select(Path.GetFileName); //returns only file names 
foreach (var filter in filters) 
{ 
    switch (filter.Action) 
    { 
     case "contains": 
      files = files.Where(f => f.Contains(filter.SearchString)); 
      break; 
     case "next action": 
      //filter here 
      break; 
    } 
} 

Если вы хотите, чтобы упростить его в более магическим образом, вы можете использовать что-то вроде var files = Directory.GetFiles(folder, "begin*middle*end*.ex*"); Но для чего-то более точным, это не будет работать, использовать длинные наматывается упомянутом выше.

+0

'GetFiles' возвращает полный путь, поэтому необходим вызов' System.IO.Path.GetFilename() '(при использовании' select' для проекта результаты должны работать нормально). Что касается вашего волшебного пути, имейте в виду, что 'searchPattern' также ищет 8.3 имена файлов, которые могут возвращать неожиданные результаты. – Setsu

0

Можно определить метод расширения, например:

public static IEnumerable<string> SearchByName(this DirectoryInfo dir, List<string> keywords) 
{ 
    foreach (FileInfo file in dir.EnumerateFiles()) 
    { 
     string fileName = Path.GetFileNameWithoutExtension(file.Name); 

     if (keywords.All(keyword => fileName.Contains(keyword))) 
     { 
      yield return file.FullName; 
     } 
    } 
} 

Вот запрос выражение эквивалент:

var dir = new DirectoryInfo(@"E:\folder"); 
var keywords = new List<string> { "test", "5" }; 

var query = from fileInfo in dir.EnumerateFiles() 
      let fileName = Path.GetFileNameWithoutExtension(fileInfo.Name) 
      where keywords.All(keyword => fileName.Contains(keyword)) 
      select fileInfo; 

foreach (var fileInfo in query) 
{ 
    Console.WriteLine(fileInfo.FullName); 
} 
Смежные вопросы