Как проверить, существует ли конкретный файл в каталоге или в любом из его подкаталогов
В С#, как проверить, существует ли конкретный файл в каталоге или в любом из его подкаталогов?
System.IO.File.Exists только, кажется, принимает единственный параметр без перегрузок для поиска подкаталогов.
Я могу сделать это с помощью LINQ и System.IO.Directory.GetFiles, используя перегрузку SearchOption.AllDirectories, но это выглядит немного тяжело.
var MyList = from f in Directory.GetFiles(tempScanStorage, "foo.txt", SearchOption.AllDirectories)
where System.IO.Path.GetFileName(f).ToUpper().Contains(foo)
select f;
foreach (var x in MyList)
{
returnVal = x.ToString();
}
Ответы
Ответ 1
Если вы ищете одно конкретное имя файла, использование *.*
действительно тяжело. Попробуйте следующее:
var file = Directory.GetFiles(tempScanStorage, foo, SearchOption.AllDirectories)
.FirstOrDefault();
if (file == null)
{
// Handle the file not being found
}
else
{
// The file variable has the *first* occurrence of that filename
}
Обратите внимание, что это не совсем то, что делает ваш текущий запрос, потому что ваш текущий запрос найдет "xbary.txt", если вы foo просто bar
. Я не знаю, преднамеренно ли это или нет.
Если вы хотите узнать о нескольких совпадениях, вы не должны использовать FirstOrDefault()
, конечно. Не ясно, что именно вы пытаетесь сделать, что затрудняет предоставление более конкретных рекомендаций.
Обратите внимание, что в .NET 4 также Directory.EnumerateFiles
, который может или не может работать лучше для вас. Я очень сомневаюсь, что это будет иметь значение, если вы ищете конкретный файл (а не все файлы в каталоге и подкаталогах), но он стоит, по крайней мере, знать. EDIT: Как отмечено в комментариях, может иметь значение, если у вас нет разрешения на просмотр всех файлов в каталоге.
Ответ 2
Альтернативой является запись функции поиска самостоятельно, одна из них должна работать:
private bool FileExists(string rootpath, string filename)
{
if(File.Exists(Path.Combine(rootpath, filename)))
return true;
foreach(string subDir in Directory.GetDirectories(rootpath, "*", SearchOption.AllDirectories))
{
if(File.Exists(Path.Combine(subDir, filename)))
return true;
}
return false;
}
private bool FileExistsRecursive(string rootPath, string filename)
{
if(File.Exists(Path.Combine(rootPath, filename)))
return true;
foreach (string subDir in Directory.GetDirectories(rootPath))
{
return FileExistsRecursive(subDir, filename);
}
return false;
}
Первый метод по-прежнему извлекает все имена каталогов и будет медленнее, когда есть много поддиректоров, но файл находится близко к вершине.
Вторая рекурсивная, которая будет медленнее в сценариях "наихудшего случая", но быстрее, когда есть много вложенных поддиреев, но файл находится в директории верхнего уровня.
Ответ 3
Чтобы проверить наличие файла в любом конкретном каталоге, выполните следующие действия:
Примечание. "UploadedFiles" - это имя папки.
File.Exists(Server.MapPath( "UploadedFiles/" ))
Наслаждайтесь кодированием
Ответ 4
Это рекурсивный поиск в файловой системе. В CodeProject есть несколько функциональных примеров:
Ответ 5
Это функция рекурсивного поиска, которая разрастается, как только находит указанный вами файл. Обратите внимание, что параметры должны быть указаны как fileName (например, testdb.bak) и каталог (например, c:\test).
Помните, что это может быть довольно медленным, если вы делаете это в каталоге с большим количеством поддиректорий и файлов.
private static bool CheckIfFileExists(string fileName, string directory) {
var exists = false;
var fileNameToCheck = Path.Combine(directory, fileName);
if (Directory.Exists(directory)) {
//check directory for file
exists = Directory.GetFiles(directory).Any(x => x.Equals(fileNameToCheck, StringComparison.OrdinalIgnoreCase));
//check subdirectories for file
if (!exists) {
foreach (var dir in Directory.GetDirectories(directory)) {
exists = CheckIfFileExists(fileName, dir);
if (exists) break;
}
}
}
return exists;
}