2010-03-15 4 views
0

Это seems like FileSystem.GetFiles() не может восстановить из исключения UnauthorizedAccessException, что .Net запускает при попытке доступа к каталогу вне пределов.Ошибка FileSystem.GetFiles() + UnauthorizedAccessException?

В этом случае это означает, что этот класс/метод не пригодится при сканировании всего диска, и я должен использовать другое решение (в этом случае: какой?)?

Вот код, чтобы показать проблему:

Private Sub bgrLongProcess_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgrLongProcess.DoWork 
    Dim drive As DriveInfo 
    Dim filelist As Collections.ObjectModel.ReadOnlyCollection(Of String) 
    Dim filepath As String 

    'Scan all fixed-drives for MyFiles.* 
    For Each drive In DriveInfo.GetDrives() 
     If drive.DriveType = DriveType.Fixed Then 
      Try 
       'How to handle "Access to the path 'C:\System Volume Information' is denied." error? 
       filelist = My.Computer.FileSystem.GetFiles(drive.ToString, FileIO.SearchOption.SearchAllSubDirectories, "MyFiles.*") 
       For Each filepath In filelist 
        DataGridView1.Rows.Add(filepath.ToString, "temp") 
        'Trigger ProgressChanged() event 
        bgrLongProcess.ReportProgress(0, filepath) 
       Next filepath 
      Catch Ex As UnauthorizedAccessException 
       'How to ignore this directory and move on? 
      End Try 
     End If 
    Next drive 
End Sub 

Спасибо.


Edit: Что об использовании Try/Поймать только, чтобы иметь GetFiles() заполнить массив, игнорировать исключение и только резюме?

Private Sub bgrLongProcess_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgrLongProcess.DoWork 
    'Do lengthy stuff here 
    Dim filelist As Collections.ObjectModel.ReadOnlyCollection(Of String) 
    Dim filepath As String 

    filelist = Nothing 
    Try 
     filelist = My.Computer.FileSystem.GetFiles("C:\", FileIO.SearchOption.SearchAllSubDirectories, "MyFiles.*") 
    Catch ex As UnauthorizedAccessException 
     'How to just ignore this off-limit directory and resume searching? 
    End Try 

    'Object reference not set to an instance of an object 
    For Each filepath In filelist 
     bgrLongProcess.ReportProgress(0, filepath) 
    Next filepath 
End Sub 

ответ

1

Положите ваше заявление об улове в цикл For each filepate in filelist. Потому что прямо сейчас, когда вы поймаете UnauthorizedAccessException, вы пропустите оставшуюся часть filelist предметов.

Редактировать

Вы правы. При попытке исключения возникает попытка try-catch, и обычно вы пытаетесь обнаружить эту ситуацию до того, как будет выбрано исключение. Один из способов сделать это в этой ситуации - проверить доступ к файлу, прежде чем что-либо делать с ним.

Для каталогов есть функция this GetAccessControl. Там is a similar function для файлов.

Возможно, вам придется разбить функцию GetFiles, чтобы сначала получать каталоги, а затем циклически перебирать каждую директорию, всегда вызывая GetAccessControl для каждого каталога и файла.

+0

Спасибо за подсказку, но я прочитал, что Try/Catch дорогостоящий и не должен быть помещен в цикл. Как насчет использования Try/Catch только для заполнения массива с помощью FileSystem.GetFiles()? – Gulbahar

+0

Спасибо, я проверю GetAccessControl, чтобы возобновить работу в случае, если этот каталог отключен. – Gulbahar

0

Для тех, кто заинтересован, я нашел следующий рабочий раствор: (. «MYFILES *», например)

http://dotnetperls.com/recursive-file-directory-vbnet

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

Public Shared Function GetFilesRecursive(ByVal initial As String, ByVal extension As String) As List(Of String) 

... так что вы можете назвать это так:

Dim list As List(Of String) = FileHelper.GetFilesRecursive("C:\", "MyFiles.*") 
0

Я использую й e следующие функции для поиска всех дисков, расположенных в системе для определенных файлов, и не прерывается, когда «GetFiles» попадает на выполнение. Это делается путем выполнения поиска только верхнего уровня с помощью «GetDirectories», который предоставит вам список каталогов базового уровня, и если он не выкинет exec, будет выполнен поиск «GetFiles» всех подкаталогов этого каталога, если выполняется затем нажмите «Каталог GetDirectories», и процесс продолжается. После каждого успешного поиска, выполняемого с помощью «GetFiles», каталоги, содержащие искомые файлы, хранятся в списке. После поиска всех существующих дисков, находящихся в системе, основная функция завершает операцию, возвращая данные, которые она добавила в список.

Public Function Left(ByVal TextString As String, ByVal LocateString As String) As String 
    Try 
     Left = Microsoft.VisualBasic.Left(TextString, InStrRev(TextString, LocateString) - 1) 
    Catch ex As Exception 
     Left = TextString 
    End Try 
End Function 

Public Function GetExistingDrives() As List(Of String) 
    Dim LocatedDrives As New List(Of String), DriveInformation As System.IO.DriveInfo() = System.IO.DriveInfo.GetDrives 
    For Each FoundDrive As System.IO.DriveInfo In DriveInformation 
     Try 
      LocatedDrives.Add(UCase(Left(FoundDrive.Name, "\"))) 
     Catch ex As Exception 
     End Try 
    Next 
    GetExistingDrives = LocatedDrives 
End Function 

Public Function LocateFiles(ByVal ParamArray SearchPattern As String()) As List(Of String) 
    Dim LocatedDirectoriesList As New List(Of String), LocatedFilenameList As System.Collections.ObjectModel.ReadOnlyCollection(Of String) 
    For Each DriveLetter In GetExistingDrives() 
     Try 
      For Each SearchDirectory As String In My.Computer.FileSystem.GetDirectories(DriveLetter, FileIO.SearchOption.SearchTopLevelOnly) 
       Try 
        LocatedFilenameList = My.Computer.FileSystem.GetFiles(SearchDirectory, FileIO.SearchOption.SearchAllSubDirectories, SearchPattern) 
       Catch ex As Exception 
       End Try 
       If (LocatedFilenameList.Count <> 0) Then 
        For Each LocatedFilename As String In LocatedFilenameList 
         Dim LocatedDirectory As String = Left(LocatedFilename, "\") 
         If (LocatedDirectoriesList.IndexOf(LocatedDirectory) = -1) Then LocatedDirectoriesList.Add(LocatedDirectory) 
        Next 
       End If 
      Next 
     Catch ex As Exception 
     End Try 
    Next 
    LocateFiles = LocatedDirectoriesList 
End Function 
Смежные вопросы