Microsoft Developer Network > Forums Home > Visual Studio Express Editions Forums > Visual Basic Express Edition > Finding empty folders in vb, and put them in a listbox.(already works, but I want it faster cause I've over 100.000 folders.
Ask a questionAsk a question
 

AnswerFinding empty folders in vb, and put them in a listbox.(already works, but I want it faster cause I've over 100.000 folders.

  • Wednesday, November 04, 2009 5:27 PMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Ok I've a problem:
    I need to make al my empty folders invisible, but the problem is that I've a lot of empty folders.
    So to do this quikly I tried to do this in VB2008.
    But I can't find out how to actually search for those files in a certain map(so all maps in My documents or something)
    and set them in a listbox, now that second isn't really a problem and I'm able to do that myself.
    Then I want to change all items in that listbox(with all the path's of the empty folders) to hide those folders.


    I got a little bit of code working:

    Dim fihiddirectory as string
    Dim fihid As FileInfo = New FileInfo(fihiddirectory)
    fi.Attributes = FileAttributes.hidden         'this is to make the file hidden.

    and then offcourse I set the listbox items in a

    for each item in listbox1.items
    fihidedirectory = item
    fi.Attributes = FileAttributes.hidden         'this is to make the file hidden.
    next

    or something like that.

     

    So All I need is a manner to find all empty directory's (the subdirectory's have to be empty too offcourse, if not than do not select)
    and place them in a listbox.


    Thank you.
     


    --------------------------------------------------------------------------------
    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)

    • Edited byme.Ryan Thursday, November 05, 2009 2:51 PM
    •  

Answers

  • Wednesday, November 04, 2009 6:24 PMLloyd Quenby Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    This is the basis of what you need to do, just pass it your first folder, it will then search each folder in turn.

    You can add your own code where show to hide folder and add to listbox


        Sub SearchFolders(ByVal DirToSearch As String)
    
            For Each DirToCheck In My.Computer.FileSystem.GetDirectories(DirToSearch, FileIO.SearchOption.SearchTopLevelOnly)
    
                'Recurse into next folder
                SearchFolders(DirToCheck)
    
                'Count files & directories
                Dim FileCount As Integer = My.Computer.FileSystem.GetFiles(DirToCheck, FileIO.SearchOption.SearchTopLevelOnly).Count
                Dim DirectoryCount As Integer = My.Computer.FileSystem.GetDirectories(DirToCheck, FileIO.SearchOption.SearchTopLevelOnly).Count
    
                'If empty do stuff
                If (FileCount < 1) And (DirectoryCount < 1) Then
                    'something done here
                End If
    
            Next
    
        End Sub
    
    
    • Marked As Answer byme.Ryan Wednesday, November 04, 2009 6:43 PM
    • Proposed As Answer byLloyd Quenby Wednesday, November 04, 2009 6:24 PM
    • Marked As Answer byme.Ryan Saturday, November 07, 2009 10:41 AM
    • Unmarked As Answer byme.Ryan Thursday, November 05, 2009 2:50 PM
    • Unproposed As Answer byme.Ryan Thursday, November 05, 2009 2:50 PM
    •  
  • Friday, November 06, 2009 7:26 AMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    No doesn't work either, cause if there's a file lets's say 10 files under one folder, than that folder can't be grayed out.


    But thanks anyway.

    Ps. Is there a way with my code:


    Dim fi As FileInfo
        Private Sub SearchFolders(ByVal DirToSearch As String, Optional ByVal hoi As String = "normal")
            Try
    top:
                For Each dirtocheck In My.Computer.FileSystem.GetDirectories(DirToSearch.ToString, FileIO.SearchOption.SearchAllSubDirectories)
                    Try
                        'Count files & directories
                        Dim FileCount1 As Integer = My.Computer.FileSystem.GetFiles(dirtocheck, FileIO.SearchOption.SearchAllSubDirectories).Count
                        'If empty do stuff
                        If (FileCount1 < 1) Then
                            TextBox2.Text += 1
                            fi = New FileInfo(dirtocheck.ToString)
                            If hoi = "normal" Then
                                fi.Attributes = FileAttributes.Hidden
                            Else
                                fi.Attributes = FileAttributes.Normal
                            End If

                        End If
                    Catch exception As Exception
                    End Try
                Next
            Catch ex As Exception
                GoTo top
            End Try
        End Sub


    To say like:

    If he checked the folder than go to the next one,
    cause when I normally do this with huge amounts of folders 3000> , the app doesn't respond at all.
    I think that that is because it tries to do all at onces.
    Hopefully you've got some ideas.


    Thanks.


    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)

    • Marked As Answer byme.Ryan Saturday, November 07, 2009 10:42 AM
    • Edited byme.Ryan Saturday, November 07, 2009 10:42 AM
    •  

All Replies

  • Wednesday, November 04, 2009 6:24 PMLloyd Quenby Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    This is the basis of what you need to do, just pass it your first folder, it will then search each folder in turn.

    You can add your own code where show to hide folder and add to listbox


        Sub SearchFolders(ByVal DirToSearch As String)
    
            For Each DirToCheck In My.Computer.FileSystem.GetDirectories(DirToSearch, FileIO.SearchOption.SearchTopLevelOnly)
    
                'Recurse into next folder
                SearchFolders(DirToCheck)
    
                'Count files & directories
                Dim FileCount As Integer = My.Computer.FileSystem.GetFiles(DirToCheck, FileIO.SearchOption.SearchTopLevelOnly).Count
                Dim DirectoryCount As Integer = My.Computer.FileSystem.GetDirectories(DirToCheck, FileIO.SearchOption.SearchTopLevelOnly).Count
    
                'If empty do stuff
                If (FileCount < 1) And (DirectoryCount < 1) Then
                    'something done here
                End If
    
            Next
    
        End Sub
    
    
    • Marked As Answer byme.Ryan Wednesday, November 04, 2009 6:43 PM
    • Proposed As Answer byLloyd Quenby Wednesday, November 04, 2009 6:24 PM
    • Marked As Answer byme.Ryan Saturday, November 07, 2009 10:41 AM
    • Unmarked As Answer byme.Ryan Thursday, November 05, 2009 2:50 PM
    • Unproposed As Answer byme.Ryan Thursday, November 05, 2009 2:50 PM
    •  
  • Wednesday, November 04, 2009 6:36 PMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Thank you, but now the problem is that I work on vista and some files are protected and can't be opened, so I got a exception that a file couldn't be opened,
    How would I do that?

    Thanks for your answer, this is definately what I need.


    Ps.
    For example:
    acces to the path C:\Users\USER1\Documents\my Pictures is denied.
    (translation from my system language.)



    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)
  • Thursday, November 05, 2009 2:47 PMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Ok I've now this:


    Private Sub SearchFolders(ByVal DirToSearch As String)
    For Each DirToCheck In My.Computer.FileSystem.GetDirectories(DirToSearch, FileIO.SearchOption.SearchTopLevelOnly)
    Try
    'Recurse into next folder
    SearchFolders(DirToCheck)
    'Count files & directories
    Dim FileCount As Integer = My.Computer.FileSystem.GetFiles(DirToCheck, FileIO.SearchOption.SearchAllSubDirectories).Count
    Dim foldercount As Integer = My.Computer.FileSystem.GetDirectories(DirToSearch, FileIO.SearchOption.SearchAllSubDirectories).Count
    'If empty do stuff
    If (FileCount < 1) Then
    ListBox1.Items.Add(DirToCheck)
    End If
    Catch exception As Exception
    End Try
    Next
    TextBox2.Text = ListBox1.Items.Count
    End Sub

     

    and to hide them I've:


    Try
    Dim fi As FileInfo
    For Each item In ListBox1.Items
    fi = New FileInfo(item.ToString)
    fi.Attributes = FileAttributes.Hidden
    Next
    Catch exception As Exception
    MessageBox.Show("Please add folders to the list.")
    End Try




    Does anyone now how I can speed it up, cause I've over 100.000 folders(I make folders for everything.)
    I thought maybe translate the whole script to c++ but I Wouldn't now were to start.
    Cause to only do like 800 folders it takes up to 10 minutes or something, and it crashes if I try to do it on all folders at ones, And that's what I want.



    thanks.


    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)
  • Thursday, November 05, 2009 3:04 PMjgalley Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Is there a reason to show the items in a list box?
    Why use the search all sub directories option?
  • Thursday, November 05, 2009 4:14 PMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    How do you mean(with the search all sub directory's)?,
    and there is not really a reason to show everthing in a listbox.
    Thanks, that will make it faster I think.(That I didn't even think of that.)


    But it is not enough to process 168.000 folders within let's say 1 hour.
    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)
  • Thursday, November 05, 2009 11:00 PMjgalley Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Try this:

    Dim todo As New List(Of DirectoryInfo)()
    todo.Add(New DirectoryInfo("C:\Temp\Junk\empty"))
    
    For i As Integer = 0 To todo.Count - 1
        Try
            todo(i).Delete()
        Catch e As System.IO.IOException
            todo.AddRange(todo(i).GetDirectories())
        End Try
    Next
    

  • Friday, November 06, 2009 7:26 AMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    No doesn't work either, cause if there's a file lets's say 10 files under one folder, than that folder can't be grayed out.


    But thanks anyway.

    Ps. Is there a way with my code:


    Dim fi As FileInfo
        Private Sub SearchFolders(ByVal DirToSearch As String, Optional ByVal hoi As String = "normal")
            Try
    top:
                For Each dirtocheck In My.Computer.FileSystem.GetDirectories(DirToSearch.ToString, FileIO.SearchOption.SearchAllSubDirectories)
                    Try
                        'Count files & directories
                        Dim FileCount1 As Integer = My.Computer.FileSystem.GetFiles(dirtocheck, FileIO.SearchOption.SearchAllSubDirectories).Count
                        'If empty do stuff
                        If (FileCount1 < 1) Then
                            TextBox2.Text += 1
                            fi = New FileInfo(dirtocheck.ToString)
                            If hoi = "normal" Then
                                fi.Attributes = FileAttributes.Hidden
                            Else
                                fi.Attributes = FileAttributes.Normal
                            End If

                        End If
                    Catch exception As Exception
                    End Try
                Next
            Catch ex As Exception
                GoTo top
            End Try
        End Sub


    To say like:

    If he checked the folder than go to the next one,
    cause when I normally do this with huge amounts of folders 3000> , the app doesn't respond at all.
    I think that that is because it tries to do all at onces.
    Hopefully you've got some ideas.


    Thanks.


    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)

    • Marked As Answer byme.Ryan Saturday, November 07, 2009 10:42 AM
    • Edited byme.Ryan Saturday, November 07, 2009 10:42 AM
    •  
  • Friday, November 06, 2009 1:39 PMjgalley Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I'm not sure I understand what it is you are attempting to do then.
    The code I provided will find and delete all folders in a tree with nothing in them.
    I guess it could result in empty folders if a parent folder contained only empty children folders.

    Actually, I don't care for my answer all that much.  One should never use exceptions the way I have done.

    Let me rewrite it for you.
  • Friday, November 06, 2009 4:47 PMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Ok thanks,

    What it is with your code is that it looks if the folder you selected doens't contains a file in it's directory(so in the folder),
    but it doesn't check the subfolders, and it doens't check if a folder doesn't contain a file in a far far subdirectory, only in it's own contents.

    Hope you understand, thanks.
    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)
  • Friday, November 06, 2009 7:16 PMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    ok I've now deleted:

     SearchFolders(dirtocheck)

    cause this maked the program redo his searsh, and we don't need that.

    Now I can do like 1800 folders at ones(And really fast too, only 10 to 20 seconds), but when I try to do 3700 at ones it doesn't respond anymore.


    Some Ideas?
    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)
  • Saturday, November 07, 2009 2:09 AMjgalley Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    actually, my code does dive into subsolders as far as they go.  The two problems with it are:

    1) it uses exceptions as part of standard work flow and that is a bad idea in general
    2) once a folder is deleted a back propagation should take place to make sure that the deleted item was not the only item.

    Technically though if you run my code it will recursively find and delete all truly empty folders (though it might  lave some new ones now empty)
  • Saturday, November 07, 2009 2:20 AMjgalley Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Try this.  It has a back propagation that should clean up folders left empty by the deletion of the only child.  
    There is a check to make sure we stay within the context of the root of the request, but use with caution.

    Dim startPath As [String] = "C:\Temp\Junk\empty"
    Dim startingDir As New DirectoryInfo(startPath)
    
    Dim todo As New Queue(Of DirectoryInfo)()
    For Each d As DirectoryInfo In startingDir.GetDirectories()
        todo.Enqueue(d)
    Next
    
    While Not todo.Count.Equals(0)
        Dim working As DirectoryInfo = todo.Dequeue()
        If Not working.Exists Then
            Continue While
        End If
        
        Dim subDirs As DirectoryInfo() = working.GetDirectories()
        If Not subDirs.Length.Equals(0) Then
            For Each d As DirectoryInfo In subDirs
                todo.Enqueue(d)
            Next
        Else
            Dim subFiles As FileInfo() = working.GetFiles()
            If subFiles.Length.Equals(0) Then
                If startingDir.FullName.ToLower() <> working.Parent.FullName.ToLower() Then
                    todo.Enqueue(working.Parent)
                End If
                working.Delete()
            End If
        End If
    End While
    
    

  • Saturday, November 07, 2009 10:06 AMme.Ryan Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Srry But your code works slower than mine(and not forget Lloyd Quenby), and "stops responding" faster than mine.(By less folders)

    But thanks anyway.
    Thanks for answering my questions, Please explain in code, and for other programming languanges than VB2008.net explain very clearly. My programming skills are:(1 to 5) Html = 4 php = 1 VB2008 = 3,5 c++ = 1 (starter)