Click here to Skip to main content
11,478,066 members (66,997 online)
Click here to Skip to main content

Recursive function to read a directory structure

, 11 Sep 2005 120.5K 1.9K 68
Rate this:
Please Sign up or sign in to vote.
How to use a recursive function to read a directory structure and save it to XML.

Introduction

In this article, I will show you how to use a recursive function to read a directory structure and then save it to XML, but first of all let me tell you the purpose of this application. I had to develop a desktop application in Flash, and it had to open audio files from the PC. I know that Flash can't execute OpenFileDialogBox and get the file path, ...but it can read XML files! So, I decided to create a default directory ("Media Library") where the user could organize the audio files in the way he wants.

But, how will the Flash know what the directory has??? From Flash I call my dirSinc.exe (.NET app.) that reads the complete "Media Library" directory structure and saves it to dirSinc.XML. In the Flash application there is a FlashTreeView (FTree component) that shows in a TreeView the content of "Media Library" and from where the user can select and open a file.

I think this introduction is enough to understand what we are gonna do...so let's go to the code!!

Using the code

I decided to do a generic example application for this article, so the form has a FolderBrowserDialog to select the folder you want to work with. When you try it, don't select the "C:\windows" directory...because it will generate an immense XML!! Wink | ;)

First of all, we have to declare the object that will manipulate the XML document. It has to be class level because it will be used by more than one function:

Public Class frmXML Inherits System.Windows.Forms.Form
    Dim xmlDoc As New XmlDocument 'Xml Document

btnSinc_Click event

Considering you already know how to create an XML document with its elements and attributes, let's focus on the createRootNode() call.

Private Sub btnSinc_Click(ByVal sender As System.Object, _
                      ByVal e As System.EventArgs) Handles 
    btnSinc.Click
    If txtPath.Text = "" Then
        Exit Sub
    End If
    Try 
        'Clears the xmlDoc for multiple process, 
        'because xmlDoc is a class level object
        xmlDoc.RemoveAll() 
        lblStatus.Text = "Readind directory structure..."
        'First Chid: Header
        xmlDoc.AppendChild(xmlDoc.CreateProcessingInstruction(_
                                          "xml", "version='1.0'"))
        createRootNode() 
        xmlDoc.Save("structure_of_" & _
          txtPath.Text.Substring(txtPath.Text.LastIndexOf("\") + 1) & _
                                                                  ".xml")
        lblStatus.Text = "The XML document was created." 
    Catch ex As Exception 
        MessageBox.Show(ex.ToString) 
    End Try
End Sub

createRootNode()

The XML format I adopted for this example has a "myRoot" node with its label and description. (This is what this Sub creates.) From here we will create the "folder" and "files" nodes with their label, description, filePath, and size attributes. Since "myRoot" node was appended, we call the loopNodes() function sending the oElmntRoot: "myRoot" node (user selected folder), txtPath.Text: the full path to the user selected folder.

loopNodes()

Finally, we are at the recursive function. Here we have two 'For Each' loops, one for folders and the other for files. We first start with the folders loop that will call itself as many times as the number of folders in order to find out if a folder has subfolders (child nodes) inside.

ofs.GetDirectories will let us loop through all the subfolders in the current folder, if true we create the XML element with its attributes, and then make the recursive call until there are no subfolders in the current folder. There begins the 'files' loop creating the corresponding XML element. But this 'file' loop doesn't make a recursive call because a file does not have subfiles. Smile | :)

Private Function loopNodes(ByVal oElmntParent As XmlElement, _
                                       ByVal strPath As String)
    Dim d As DirectoryInfo
    Dim ofs As New DirectoryInfo(strPath & "\")
    
    'Folders Loop -------------------------------------------------
    
    'Gets the directories of the current node. 
    'It changes for each recursive call
    For Each d In ofs.GetDirectories  
        'Manipulates the sub folders nodes
        Dim oElmntChild As XmlElement  
        oElmntChild = xmlDoc.CreateElement("folder") 
        oElmntChild.SetAttribute("label", d.Name) 
        'Adds the "folder" node
        oElmntParent.AppendChild(oElmntChild) 
        'Recursive call
        loopNodes(oElmntChild, strPath & "\" & d.Name) 
    Next
    
    'Files Loop ------------------------------------------------------ 
    
    Dim oFile As FileInfo
    For Each oFile In ofs.GetFiles
        Dim oElmntLeaf As XmlElement 'Manipulates the files nodes
        oElmntLeaf = xmlDoc.CreateElement("file")
        oElmntLeaf.SetAttribute("label", oFile.Name)
        oElmntLeaf.SetAttribute("filePath", strPath)
        oElmntLeaf.SetAttribute("bytesSize", CType(oFile.Length, String))
        oElmntParent.AppendChild(oElmntLeaf) 'Adds the "file" node
    Next
End Function

The key point to understand in the recursive function is that when it calls itself it creates new instances of the objects inside, and when it finishes, returns to the point from where it was called. May be the first time you'll need to debug the function step by step to understand what is happening in each loop.

Tip: This function could be used to fill a TreeView, provided the structure is not very big. In that case it maybe better to fill the folders while you open each one.

Hope this article helps you!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Damian Castroviejo
Web Developer
United States United States
I started working as Multimedia/Web designer in Buenos Aires in 1998, and later on I felt attraction for coding.
I specialized in Vb.Net languaje, but I also like to code in C#, ActionScript and clasic ASP.
I'm currently working in Miami area.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Member 102459371-Sep-13 11:28
memberMember 102459371-Sep-13 11:28 
GeneralMy vote of 5 Pin
satishk4u12-Jan-11 21:47
membersatishk4u12-Jan-11 21:47 
GeneralThanks Pin
GlimmerMan18-Nov-10 12:54
memberGlimmerMan18-Nov-10 12:54 
GeneralMy vote of 5 Pin
myaccountram14-Aug-10 10:51
membermyaccountram14-Aug-10 10:51 
GeneralAwesome Post Pin
Vijay Mesa19-Oct-09 5:09
memberVijay Mesa19-Oct-09 5:09 
QuestionI need this too but in C++ Pin
Carl Owen28-Jul-08 12:36
memberCarl Owen28-Jul-08 12:36 
GeneralRequest Pin
eyemkent9-May-08 22:29
membereyemkent9-May-08 22:29 
GeneralRe: Request Pin
Damian Castroviejo10-May-08 8:05
memberDamian Castroviejo10-May-08 8:05 
GeneralThanks Pin
jomet5-Mar-08 0:07
memberjomet5-Mar-08 0:07 
GeneralRe: Thanks Pin
Damian Castroviejo6-Mar-08 10:57
memberDamian Castroviejo6-Mar-08 10:57 
Questionbroken links & missing code Pin
rcbrules22-Oct-07 14:18
memberrcbrules22-Oct-07 14:18 
AnswerRe: broken links & missing code Pin
Damian Castroviejo24-Oct-07 18:11
memberDamian Castroviejo24-Oct-07 18:11 
GeneralRecursive function to create a directory structure Pin
skvikram8-Nov-06 20:10
memberskvikram8-Nov-06 20:10 
GeneralRe: Recursive function to create a directory structure Pin
Damian Castroviejo9-Nov-06 16:16
memberDamian Castroviejo9-Nov-06 16:16 
GeneralVery good article Pin
Austin Amuok6-Jan-06 19:47
memberAustin Amuok6-Jan-06 19:47 
GeneralThis is Exactly what I needed! Pin
mizzl232mike14-Nov-05 11:59
membermizzl232mike14-Nov-05 11:59 
GeneralRe: This is Exactly what I needed! Pin
Damian Castroviejo16-Nov-05 15:28
memberDamian Castroviejo16-Nov-05 15:28 
GeneralRe: This is Exactly what I needed! Pin
mizzl232mike16-Nov-05 21:19
membermizzl232mike16-Nov-05 21:19 
GeneralRe: This is Exactly what I needed! Pin
Damian Castroviejo17-Nov-05 18:37
memberDamian Castroviejo17-Nov-05 18:37 
GeneralSome suggestions Pin
Pete Appleton13-Sep-05 23:11
memberPete Appleton13-Sep-05 23:11 
GeneralAnother similar work Pin
Alberto Venditti13-Sep-05 13:43
memberAlberto Venditti13-Sep-05 13:43 
Generaldon't use this in production-code Pin
KristofVerbiest12-Sep-05 1:44
memberKristofVerbiest12-Sep-05 1:44 
GeneralRe: don't use this in production-code Pin
Damian Castroviejo12-Sep-05 4:31
memberDamian Castroviejo12-Sep-05 4:31 
GeneralRe: don't use this in production-code Pin
Kristof Verbiest31-May-06 2:04
memberKristof Verbiest31-May-06 2:04 
GeneralRe: don't use this in production-code Pin
tex85964-Jun-06 5:26
membertex85964-Jun-06 5:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150520.1 | Last Updated 11 Sep 2005
Article Copyright 2005 by Damian Castroviejo
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid