2013-05-17 2 views
3

У меня есть эта строка кода: (с использованием LINQ)Как получить только файлы, которые можно скопировать?

//string folder <-- folder browser dialog. 
listFiles = Directory.GetFiles(folder, "*.xml", 
       SearchOption.AllDirectories).Select(
        fileName => Path.GetFullPath(fileName)).ToList(); 

Но иногда моя программа находит защищенные файлы, такие как системные файлы или даже системные папки, которые не могут быть открыты.

Как я могу превзойти эту проблему:

получить только имя файла открытых/свободных файлов-папок.

ответ

4

Это может быть проблемой. Если он выдает исключение при просмотре каталогов, он останавливается.

Если вы хотите, чтобы игнорировать эти каталоги и продолжайте идти, вы должны написать рекурсивный метод, чтобы сделать это:

List<string> GetFiles(string folder, string filter) 
{ 
    List<string> files = new List<string>(); 
    try 
    { 
     // get all of the files in this directory 
     files.AddRange(Directory.GetFiles(folder, filter)); 
     // Now recursively visit the directories 
     foreach (var dir in Directory.GetDirectories(folder)) 
     { 
      files.AddRange(GetFiles(dir, filter)); 
     } 
    } 
    catch (UnauthorizedAccessException) 
    { 
     // problem accessing this directory. 
     // ignore it and move on. 
    } 
    return files; 
} 

Несколько больше памяти эффективная версия будет:

private List<string> GetFiles(string folder, string filter) 
    { 
     var files = new List<string>(); 

     // To create a recursive Action, you have to initialize it to null, 
     // and then reassign it. Otherwise the compiler complains that you're 
     // using an unassigned variable. 
     Action<string> getFilesInDir = null; 
     getFilesInDir = new Action<string>(dir => 
      { 
       try 
       { 

        // get all the files in this directory 
        files.AddRange(Directory.GetFiles(dir, filter)); 
        // and recursively visit the directories 
        foreach (var subdir in Directory.GetDirectories(dir)) 
        { 
         getFilesInDir(subdir); 
        } 
       } 
       catch (UnauthorizedAccessException) 
       { 
        // ignore exception 
       } 
      }); 

     getFilesInDir(folder); 
     return files; 
    } 
+0

Я использую LINQ внутри «DoWork» (backgroundWorker), потому что кажется легким ... но я попробую это. –

+0

Работал, но теперь мне нужно изменить остальную часть моего кода. :) –

8

Вы не можете сказать, вам просто нужно поймать исключение.

Что делать, если файл является бесплатным при выполнении бесплатной проверки, но используется при обработке?

+0

Он останавливается когда выбрано исключение. :( –

+1

Затем поймайте его и продолжайте. Вам нужно обернуть код, обрабатывающий один файл внутри блока try/catch, захватить ** конкретное исключение **, которое вы знаете, как обращаться, а затем игнорировать это. а не ** поймать базовый класс 'Exception'. –

1

вы могли бы использовать что-то вроде этого, потенциально вы должны настроить атрибут проверки:

Directory.GetFiles(folder, "*.xml", SearchOption.AllDirectories) 
    .Select(fileName => new FileInfo(Path.GetFullPath(fileName))) 
    .Where(n => !n.Attributes.HasFlag(FileAttributes.System)) 
    .Select(n => n.FullName) 
    .ToList(); 
+0

Здесь он показывает System.IO.File.Attributes не содержит определения для HasFlag ... –

+0

Я тестировал его на своем VS2012, и он отлично работает. Enum реализует HasFlag с тех пор .NET 4 - я думаю, вы можете использовать стандартный побитовый и вместо этого. – dkozl

+0

О, у меня есть 3.5 –