none
Проблема с поиском. RRS feed

  • Вопрос

  • Знатоки хелп!
    есть метод поиска, вот его фрагмент:

    try
    {
        Files = System.IO.Directory.GetFiles(Path, Mask, SearOpt);
        for (int i = 0; i < Files.Count(); i++)
        {
            if ((System.IO.Path.GetFileName(Files[i])).Contains(Text))
            {
                System.IO.FileInfo Fi = new System.IO.FileInfo(Files[i]);
                string _Path = System.IO.Path.GetDirectoryName(Files[i]);
                if (_Path.Substring (_Path.Length - 1, 1) == @"\") _Path = _Path.Remove(_Path.Length - 1, 1);
                Invoke(
                    new Action(
                        delegate
                        {
                            dataGridView1.Rows.Add(DisplayCount += 1, System.IO.Path.GetFileName(Files[i]), ConvertToDoble(Fi.Length), _Path);
                        }));
            }
        }
    }
    catch { }

    Проблема в том, что этот код наткнувшись на папку в которую не имеет доступа (System Volume Information) вылетает, как сделать так, чтобы после того как поиск наткнется на подобную папку или файл пропускал ее и выполнялся дальше.

    Система Win7 x64

    Да, и еще вопрос, есть соображения как прикрутить сюда прогресс бар? Ведь речь идет о неявном выражении (неизвестно сколько будет файлов)?

    • Перемещено Tagore Bandlamudi 3 октября 2010 г. 0:47 MSDN Forums consolidation (От:Форум по .NET Framework)
    21 февраля 2010 г. 5:39

Ответы

  • Пример исполнения чего? Самого рекурсивного поиска?
    Что-то вроде:
    static void Main(string[] args)
    {
        string path = @"d:\projects";
        string mask = "*.cs";
    
        foreach (string file in FindFilesRec(path, mask))
        {
            Console.WriteLine(file);
        }
    }
    
    static IEnumerable<string> FindFilesRec(string path, string searchPattern)
    {
        string[] files;
        try
        {
            files = Directory.GetFiles(path, searchPattern);
        }
        catch (UnauthorizedAccessException)
        { 
            // log
            yield break;
        }
    
        foreach (string file in files)
        {
            yield return file;
        }
    
        string[] directories;
        try
        {
            directories = Directory.GetDirectories(path);
        }
        catch (UnauthorizedAccessException)
        {
            // log
            yield break;
        }
    
        foreach (string subdirectory in directories)
        {
            foreach (string file in FindFilesRec(subdirectory, searchPattern))
            {
                yield return file;
            }
        }
    }
    

    • Помечено в качестве ответа JusteG 26 февраля 2010 г. 6:54
    25 февраля 2010 г. 21:26

Все ответы

  • Спасибо за информацию, но это немного не в тему...
    Я справшивал как сделать так, чтобы код наткнувшись на ошибку продолжал выполнятся, а не как предоставить права доступа к ресурсам компьютера...

    Тема открыта.
    22 февраля 2010 г. 12:15
  • я про то, что при помощи него можно попробовать проверять права на доступ.
    А вообще оберните   System.IO.FileInfo Fi = new System.IO.FileInfo(Files[i]); в отдельный метод, вроде такого

    public bool TryGetFileInfo(string file, out FileInfo info)
    {
      try
      {
         info = new System.IO.FileInfo(Files[i]); 
         return true;
      }
      catch
      {
         return false;
      }
    }

     


    [Мой блог], [LinkedIn]
    22 февраля 2010 г. 12:26

  • Извините, возможно я не достаточно ясно выразил свои мысли, поясняю, если убрать метод try, и запустить поиск по диску D:\, мы получим следующее:
    Через несколько мнгновений код выдаст вот такую вот ошибку: "{"Отказано в доступе по пути \"D:\\System Volume Information\"."}" в строке "Files = System.IO.Directory.GetFiles(Path, Mask, SearOpt);" и, не дав никакого результата, вылетит. Если заключить весь цикл в метод try, от вылета я ограждаюсь, только результата никакого не вижу. Мне нужно сделать так, чтобы при любой ошибке в методе поиска, код ее пропускал, и выполнялся дальше как ни в чем не бывало. Нет доступа к папке, ну и черт с ней, пойду в следующую, неможет прочитать свойства файла, и бог с ним, к следующему файлу. Вот о чем я спрашивал, а не о том как проверить есть ли доступ. Далее, я не случайно указал свою ОС, т.к. на других компьютерах, с ОС Win XP программа такого поведения не выказывает. Да и я про прогресс бар спрашивал... как его сюда прикрутить?
    По существу, будте добры.

     

    22 февраля 2010 г. 13:29
  • Извините, но телепаты в отпуске ;)

    В общем вы запихиваете в третий параметр SearchOption.AllDirectories, делайте с SearchOption.TopDirectoryOnly и рекурсивно запускайте свою функцию по поддиректориям.
    [Мой блог], [LinkedIn]
    22 февраля 2010 г. 14:48
  • Думал об этом, но неужели нет способа проще?
    Ведь для этого придется заводить массив, с дирректориями, а мне не хотелось бы...
    А что там с прогрессом? трудность в том что неизвесто в начале сколько там вообще будет файлов и дирректорий/поддиректорий, есть соображения?

    22 февраля 2010 г. 15:09
  • Необходимость массива не понял. Просто вызывать рекурсией. Обойтись без прогресс бара. Все равно даже в вашем случае самое основное - это вызов первого метода


    [Мой блог], [LinkedIn]
    22 февраля 2010 г. 15:41
  • Ну как нет необходимости?
    Вот алгоритм который я на вскидку вижу:
    1. Объявляем массив.
    2. Первым членом записываем исходный путь поиска.
    3. Запускаем рекусией по массиву код:
        Берем элемент массива = Счетчик
        Если значение существует
           Счетчик +1
           Все дирректории в конец массива
           Все файлы в дата грид

    т.о. код просканирует все поддирректории, а как без него? чета не допру...

    • Изменено JusteG 25 февраля 2010 г. 17:32
    25 февраля 2010 г. 17:22
  • У когонибудь есть еще соображения в тему?
    Не стесняемся, предлагаем...
    25 февраля 2010 г. 17:25
  • Теоретически невозможно сделать честный прогрессбар на заранее неизвестном количестве объектов. Он или будет бежать неравномерно (как в инсталляторе винды), или будет иногда отбегать назад, при получении более точного количества поддиректорий.
    25 февраля 2010 г. 18:17
  • Ребят, вы меня конечно извините, но я всего пару месяцев пишу на C#. Если возможно, советы с примерами пожалуйста, спасибо.
    Значит подведем черту?
    Поиск рекусией, честный прогресс неполучится... Думал будет проще, неужели MS не придумали какойнить параметр при запуске поиска или какуюнить универсальную catch команду на случай ошибки во время поиска.
    PashaPash Медали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя Можно пример исполнения ну или хотябы алгоритм, чет я не соображу... от чего отталкиваться?
    25 февраля 2010 г. 19:43
  • Пример исполнения чего? Самого рекурсивного поиска?
    Что-то вроде:
    static void Main(string[] args)
    {
        string path = @"d:\projects";
        string mask = "*.cs";
    
        foreach (string file in FindFilesRec(path, mask))
        {
            Console.WriteLine(file);
        }
    }
    
    static IEnumerable<string> FindFilesRec(string path, string searchPattern)
    {
        string[] files;
        try
        {
            files = Directory.GetFiles(path, searchPattern);
        }
        catch (UnauthorizedAccessException)
        { 
            // log
            yield break;
        }
    
        foreach (string file in files)
        {
            yield return file;
        }
    
        string[] directories;
        try
        {
            directories = Directory.GetDirectories(path);
        }
        catch (UnauthorizedAccessException)
        {
            // log
            yield break;
        }
    
        foreach (string subdirectory in directories)
        {
            foreach (string file in FindFilesRec(subdirectory, searchPattern))
            {
                yield return file;
            }
        }
    }
    

    • Помечено в качестве ответа JusteG 26 февраля 2010 г. 6:54
    25 февраля 2010 г. 21:26