Подтвердить что ты не робот

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

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

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();
}  
4b9b3361

Ответ 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/" ))

Наслаждайтесь кодированием

Ответ 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;
    }