Eumerate Sub-Folders

All,

I am trying to write something that you can point it to a directory, ex. c:\library, and it will tell me what the sub-folders are in that directory.

The reason that I am doing this would be to create something of a dynamic library.  I am looking to have each sub-directory be put into a treeview control as categories.  Then when you click on a category it will enumerate the files that are within this category.  I know that this is basically a file browser, but it is simply something that I am curious about and could use currently.

Thank you all for your time,
Mabuti


Answer this question

Eumerate Sub-Folders

  • Johan Fourie

    Reed,

    To be honest, your function is very compact, and I think it's just as fast with less resources needed.  I'm not really going to take time to benchtest it (my bench-test machine burned a few sticks of ram already, and I'm not interested in burning the last 512 on it), but I didn't know you can enumerate like that.  Granted, I'm a more modular developer that likes to see things as it's happening, and I fell in love with that intermediate window back in the vb6 days.  

    I'm not sure if you're able to avoid that try/catch since IO exceptions occur for all sorts of reasons. 

    Does anyone else that visit the board spent a lot of time on the IO   A lot of Xml based developers will probably handle file systems, and I'm wondering if there's other ways that this was done.  The example I have is honestly my first real attempt at winforms via .NET last year (besides the dinky two form with three buttons total for some manager that can't figure out xsl) and it's lacking a lot of cool things that I do now.  :)  So learning is definitely an addiction of mine.

    I'll try to look into some Win32 api's to see if it can be done that way, but there might be a good way with straight .NET.  

    Let's keep this thread alive.  It excites my brain.
     

  • Robin Xu

    Thank you both for the replies, very very helpful.  Here is rkimble's example in C# form for anyone that would like it in that form.  The only difference is that it returns a ArrayList not a string array:

    public ArrayList GetFolderList(string FilePath, bool ShowErrors) 

    ArrayList lst = new ArrayList(); 
    IEnumerator enm; 
    int cnt = 0; 
    string curPath = FilePath; 
    lst.Add(curPath); 
    bool IsDone = false; 
    while (!(IsDone)) 

    try 

    enm = System.IO.Directory.GetDirectories(curPath).GetEnumerator(); 
    while (enm.MoveNext()) 

    lst.Add(((string)(enm.Current))); 


    catch (Exception ex) 

    if (ShowErrors) 

    lst[cnt] += " *(" + ex.Message + ")"; 


    finally 

    cnt += 1; 
    if (cnt == lst.Count) 

    IsDone = true; 

    else 

    curPath = lst[cnt].ToString(); 



    lst.Sort(); 

    return lst; 
    }

    Thanks again.
    -Mabuti

  • BuffaloJ

    KraGiE,

    Thanks for the reply.  I do have one question.  Where is the method that this line of code is looking for "GetDirectoriesInFolder"

    GetDirectoriesInFolder(ref oLoopInternalList, oTempDirectoryList[i].ToString());

    Thank you again for your time.

    -Mabuti

  • anshubansal2000

    My bad.  :)  This is why it's bad to do copy/paste programming.  hehe


    /// <summary>
    /// Gets the list of files within the entered folder.
    /// </summary>
    /// <param name="oFileList">byRef ArrayList containing the files.</param>
    /// <param name="sDirectory">string Directory to browse.</param>
    public void GetFilesInFolder(ref ArrayList oFileList, string sDirectory) 
    {
    // loop the directory for filenames
    foreach(string sFileName in System.IO.Directory.GetFiles(sDirectory))
    {
    // use w/o if statement if you're not just parsing images.
    // verify they're a .jpg or .gif
    if (sFileName.ToLower().Trim().EndsWith(".jpg") || sFileName.ToLower().Trim().EndsWith(".gif")) 
    {
    // add the new file into the arraylist.
    oFileList.Add(sFileName);
    System.Diagnostics.Debug.WriteLine(sFileName);
    }
    }
    }

    /// <summary>
    /// Retrieves the sub-directories and adds them to the array list that's entered in by reference.
    /// </summary>
    /// <param name="oDirectoryList">byRef ArrayList contains the list of directories.</param>
    /// <param name="sDirectory">string Directory to browse.</param>
    public void GetDirectoriesInFolder(ref ArrayList oDirectoryList, string sDirectory) 
    {
    // loop the directory for sub directories.
    foreach(string sNewDirectory in System.IO.Directory.GetDirectories(sDirectory)) 
    {
    // Add the new sub-directory.
    oDirectoryList.Add(sNewDirectory);
    System.Diagnostics.Debug.WriteLine(sNewDirectory);
    }
    }

    /// <summary>
    /// Static method used to check if a directory exists and create if it doesn't.
    /// </summary>
    /// <param name="directory">string</param>
    /// <returns>bool</returns>
    public static bool CreateDirectory(string directory) 
    {
    if (!System.IO.Directory.Exists(directory)) 
    {
    System.IO.Directory.CreateDirectory(directory);
    }
    return (System.IO.Directory.Exists(directory));
    }


    That's the rest of the functions in that region.  if you want to download the entire source.. it's a bit old, and I wrote it haphazardly for a friend.. so it's kinda lacking since I didn't really finish it.

    You can download the source at www.inklass.com/imageresizerv2Source.zip or www.alloutasp.net/imageresizerv2Source.zip the version just means I had to add some new things for him.  It's kinda neat, but doesn't replace a well designed adobe macro.

  • Mark Swinkels

    ^ Nice.  I like that one.  
  • TimothyJ


    /// <summary>
    /// Loops to return all sub-directories.
    /// </summary>
    /// <param name="sDirectory">string</param>
    /// <returns>System.Collections.ArrayList</returns>
    public ArrayList GetAllSubDirectories(string sDirectory) 
    {
    ArrayList oDirectoryList = new ArrayList();
    // insane loop
    ArrayList oTempDirectoryList = new ArrayList();
    ArrayList oLoopInternalList = new ArrayList();
    do 
    {
    if (oTempDirectoryList.Count > 0) 
    {
    for (int i=0;i<oTempDirectoryList.Count;i++) 
    {
    if (!oTempDirectoryList[i].Equals("no more"))
    GetDirectoriesInFolder(ref oLoopInternalList, oTempDirectoryList[i].ToString());
    else
    oTempDirectoryList.Remove("no more");
    }
    oDirectoryList.AddRange(oTempDirectoryList);
    oTempDirectoryList.Clear();
    if (oLoopInternalList.Count > 0)
    oTempDirectoryList.AddRange(oLoopInternalList);
    else
    oTempDirectoryList.Add("no more");

    oLoopInternalList.Clear();
    }
    else 
    {
    // another loop
    GetDirectoriesInFolder(ref oTempDirectoryList, sDirectory);
    if (oTempDirectoryList.Count == 0) 
    oTempDirectoryList.Add("no more");
    }

    } while (oTempDirectoryList[0].ToString() != "no more";

    // clear array lists
    oTempDirectoryList.Clear();
    oLoopInternalList.Clear();

    oTempDirectoryList = null;
    oLoopInternalList = null;

    return oDirectoryList;
    }

  • David Belgium

    Doh!

    Recursion....  this is a bit faster:

    Get all entries (files and folders)

    Dim myRes as New ArrayList

        Private Sub GetData(ByVal source As String)
            If System.IO.Directory.Exists(source) Then
                For Each d As String In System.IO.Directory.GetFileSystemEntries(source)
                    myRes.Add(d)
                    GetData(d)
                Next
            End If

        End Sub


    Get folders only

    Dim myRes as New ArrayList

        Private Sub GetData(ByVal source As String)
             For Each d As String In System.IO.Directory.GetDirectories(source)
                myRes.Add(d)
                GetData(d)
            Next

        End Sub

  • nlr

    Here's a pretty straight-forward little function that returns an alphabetized list (string array) of all folders and subfolders contained within a given root.  The Try Block is used to catch folders the user does not have access to.  Specify True for ShowErrors to have error info appended to the offending path.


        Public Function GetFolderList(ByVal FilePath As String, Optional ByVal ShowErrors As Boolean = False) As String()
            Dim lst As New ArrayList
            Dim enm As IEnumerator
            Dim cnt As Integer = 0

            Dim curPath As String = FilePath
            lst.Add(curPath)

            Dim IsDone As Boolean = False
            Do While Not IsDone
                Try
                    enm = System.IO.Directory.GetDirectories(curPath).GetEnumerator
                    While enm.MoveNext
                        lst.Add(CType(enm.Current, String))
                    End While
                Catch ex As Exception
                    If ShowErrors Then
                        lst.Item(cnt) &= " *(" & ex.Message & ")"
                    End If
                Finally
                    cnt += 1
                    If cnt = lst.Count Then
                        IsDone = True
                    Else
                        curPath = lst(cnt)
                    End If
                End Try
            Loop

            lst.Sort()
            Return lst.ToArray(GetType(String))

        End Function


  • FireWave

    TY =)

    It would be better if it checked accessibility of the folder without the Try block (encountering a folder that throws an exception slows down the routine considerably), but the try block keeps the example of building the list simple.

  • GiPer

    To be honest, I think my example is overkill.  :)

    What you should do is just get System.IO.Directory.GetDirectories(path).  It returns the sub-directories in the selected path as a string array.  I'm terribly sorry about the whole multiple loop thing.  I didn't carefully read the original question.. maybe I'll make a rule not to post after 10pm or something.  :)  Anyways, the way I showed you will literally give you a list of ALL the sub-directories from start to end.  :)  It's because I was building a photo gallery resizer where you link to one directory, and everything under it will become resized for web.  


  • Eumerate Sub-Folders