Ошибка "Незаконные символы в пути" с использованием подстановочных знаков с помощью Directory.GetFiles
У меня есть каталог с несколькими подкаталогами, которые содержат файлы .doc. Пример:
C:\Users\user\Documents\testenviroment\Released\test0.doc
C:\Users\user\Documents\testenviroment\Debug\test1.doc
C:\Users\user\Documents1\testenviroment\Debug\test2.doc
C:\Users\user\Documents1\testenviroment\Released\test20.doc
Я хочу получить все файлы test*.doc
во всех папках отладки. Я пробовал:
string[] files = Directory.GetFiles(@"C:\Users\user", "*Debug\\test*.doc",
SearchOption.AllDirectories);
И это дает мне ошибку "Недопустимые символы в пути".
Если я попробую:
string[] files = Directory.GetFiles(@"C:\Users\user", "\\Debug\\test*.doc",
SearchOption.AllDirectories);
Я получаю другую ошибку: "Не удалось найти часть пути C:\Users\user\Debug".
Ответы
Ответ 1
Вы включаете папку в шаблон поиска, который не ожидается. Согласно docs:
searchPattern Тип: System.String Строка поиска для соответствия имена файлов в пути. Этот параметр может содержать комбинацию действительных буквенных путей и символов подстановки (* и?) (см. Примечания), но не поддерживает регулярные выражения.
С учетом этого попробуйте что-то вроде этого:
String[] files = Directory.GetFiles(@"C:\Users\user", "test*.doc", SearchOption.AllDirectories)
.Where(file => file.Contains("\\Debug\\"))
.ToArray();
Это приведет к получению ВСЕХ файлов в указанном каталоге и возвращает их с помощью Debug
в пути. Имея это в виду, постарайтесь, чтобы каталог поиска был сужен как можно больше.
Примечание:
В мой первоначальный ответ включен EnumerateFiles, который будет работать следующим образом (убедитесь, что вы передали поиск (спасибо @CodeCaster)):
String[] files = Directory.EnumerateFiles(@"C:\Users\user", "test*.doc", SearchOption.AllDirectories)
.Where(file => file.Contains("\\Debug\\"))
.ToArray();
Я только что запустил тест, а второй, кажется, медленнее, но может быть быстрее в большой папке. Стоит иметь в виду.
Изменить: примечание от @pinkfloydx33
На самом деле у меня это фактически сняло систему, которую я по наследству. Это заняло много времени, пытаясь вернуть массив и убивая также память. Проблема была отклонена преобразованием к перечислимым коллегам
Таким образом, использование второго варианта будет более безопасным для больших каталогов.
Ответ 2
Второй параметр, шаблон поиска, работает только для имен файлов. Таким образом, вам нужно будет перебирать каталоги, которые вы хотите выполнить, а затем вызвать Directory.GetFiles(directory, "test*.doc")
в каждом каталоге.
Как написать этот код, зависит от того, насколько он вам нужен и какие предположения вы хотите сделать (например, "все каталоги Debug всегда находятся в двух уровнях в каталоге пользователя" по сравнению с "каталогом Debug" может быть на любом уровне в каталог пользователя ").
Смотрите Как рекурсивно перечислить все файлы в каталоге на С#?.
В качестве альтернативы, если вы хотите искать все подкаталоги, а затем отбрасывать файлы, которые не соответствуют вашим предпочтениям, см. Рекурсивный поиск файла в каталогах:
var files = Directory.GetFiles(@"C:\Users\user", "test*.doc", SearchOption.AllDirectories)
.Where(f => f.IndexOf(@"\debug", StringComparison.OrdinalIgnoreCase) >= 0);
Но обратите внимание, что это может быть плохо для производительности, поскольку оно сканирует нерелевантные каталоги.