i have the following code for getting the number of files on a drive:

Dim num As Integer = 0
        Dim drive As String = "C:"

For Each File In System.IO.Directory.GetFiles(drive,"*",System.IO.SearchOption.AllDirectories)
            Try
                num += 1
                Label5.Text = String.Format("Files found: {0}", num)
                If num > 50 Then
                    RaiseEvent start()
                End If
                ProgressBar1.Maximum = num
            Catch ex As Exception
                Continue For              //Continue Loop
            End Try
        Next

I want to skip the files which i dont have access to. But my error is occuring before the try hence i am not able to continue the loop.
Please advice on how should i continue the for loop disregarding the error.

Regards
BattleX

Dani AI

Generated

The exception happens before your Try because Directory.GetFiles(..., SearchOption.AllDirectories) builds the full file list up front. If any subtree is inaccessible that initial call throws and your inner Try never runs. Two robust approaches: 1) enumerate per-directory and catch exceptions at each directory boundary, or 2) use lazy enumeration (Directory.EnumerateFiles) and still handle exceptions where they occur. Both let you skip inaccessible locations and continue.

A safe, lazy walker that skips directories you cannot open (and yields file names so you can process them on the fly) looks like this:

Iterator Function EnumerateFilesSafe(root As String) As IEnumerable(Of String)
    Dim dirs As New Stack(Of String)
    dirs.Push(root)

    While dirs.Count > 0
        Dim current As String = dirs.Pop()
        Dim files() As String = New String() {}

        Try
            files = System.IO.Directory.GetFiles(current)
        Catch ex As UnauthorizedAccessException
            Continue While
        Catch ex As Exception
            Continue While
        End Try

        For Each f As String In files
            Yield f
        Next

        Dim subdirs() As String = New String() {}
        Try
            subdirs = System.IO.Directory.GetDirectories(current)
        Catch ex As Exception
            Continue While
        End Try

        For Each d As String In subdirs
            dirs.Push(d)
        Next
    End While
End Function

Usage notes and practical tips

  • Process names as they come instead of building one huge array; write to disk or stream results if memory is a concern.
  • Update the UI infrequently (for example every 100 files) or use BackgroundWorker/Task with Progress to avoid flicker and UI freezes. Only touch Label/ProgressBar on the UI thread (Invoke/ReportProgress).
  • Don’t repeatedly set ProgressBar.Maximum inside the loop; set it once when you know the total. If you need an exact total you must do a separate (expensive) count pass, otherwise use an indeterminate/Marquee style or update a scaled percentage.
  • Catch specific exceptions (UnauthorizedAccessException, PathTooLongException, IOException) rather than swallowing everything silently and log unexpected failures.

As showed, catching exceptions around directory traversal works; ’s flicker was caused by resetting the label at each call. The iterator above avoids preloading everything and gives you per-directory control so inaccessible folders are skipped without aborting the whole operation.

Recommended Answers

All 7 Replies

Member Avatar for Member #857553

Use this recursive method. It allows you to trap the exception and continue.

I put together another version that tested the access rights first but took 60% longer than just catching the exeception.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     
    Dim path As String = "C:\"
    Dim TotalFiles As Integer = GetDirectoryFileCount(path)

End Sub

Private Function GetDirectoryFileCount(ByVal directoryPath As String) As Integer

    Dim TotalFiles As Integer

    Try
        TotalFiles += System.IO.Directory.GetFiles(directoryPath).Count

        For Each Directory As String In System.IO.Directory.GetDirectories(directoryPath)
            TotalFiles += GetDirectoryFileCount(Directory)
        Next

    Catch ex As Exception

    End Try

    Return TotalFiles

End Function

Thank you for your prompt response

When i tried to display the current status of the files searched by using a label it keeps going to zero and flicks to another number and again zero. But however in the end it is giving me the correct value.

Dim TotalFiles As Integer
        Label5.Text = 0
        Try
            TotalFiles += System.IO.Directory.GetFiles(directoryPath).Count


            For Each Directory As String In System.IO.Directory.GetDirectories(directoryPath)
                TotalFiles += GetDirectoryFileCount(Directory)
                Label5.Text = TotalFiles                              //Is this correct??
            Next

        Catch ex As Exception

        End Try

        Return TotalFiles

    End Function

Is the label5.text = TotalFiles at correct position? I need to get the progress of the files counted..

Regards
BattleX

Sorry i got my error :

i have put label5.text = 0 in the start of the function ooopsss

Thanx again!!

I also want to get the names of the files..

The method in the link skips a complete top director if access is denied.
For example if my C drive contains the following folders:

Program Files
Users
etc
if access is denied to any file in Program files it completely skips program files and moves on to Users

Thanks any way learned about the UnauthorizedAccessException from it :-)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.