Why is this code working? Recursive Event

ilan

Expert
Licensed User
Longtime User
hi

i would like to understand why and how this code is working. i know it works but would like to understand why:

B4X:
Sub DeleteFolder (folder As String)
   For Each f As String In File.ListFiles(folder)
       If File.IsDirectory(folder, f) Then
           DeleteFolder(File.Combine(folder, f))
       End If
       File.Delete(folder, f)
   Next
End Sub

so lets say i want to delete all files and sub folder of: C:\music

my folder looks like this:

music has 3 sub folders: hip hop, rock, country. each folder has 3 songs in it.

music it self also has 3 files besides the 3 subfolders.

now lets starts the loop:

DeleteFolder("C:\music")

what will happen?

'File 1

B4X:
[CODE=b4x]Sub DeleteFolder (folder As String)

   For Each f As String In File.ListFiles(folder) 'so folder is here on first start c:\music
       If File.IsDirectory(folder, f) Then  'first file is not a folder so it will be skipped and delete the file
           DeleteFolder(File.Combine(folder, f))
       End If
       File.Delete(folder, f) 'here is file 1 deleted
   Next

End Sub
[/CODE]

'File 2

B4X:
[CODE=b4x]Sub DeleteFolder (folder As String)

   For Each f As String In File.ListFiles(folder) 'the folder name is still the same c:\music
       If File.IsDirectory(folder, f) Then  'second file IS A FOLDER it is HIP HOP so now the condition is true and we will jump to the next line
           DeleteFolder(File.Combine(folder, f)) ' here we start the method again and EXIT the existing run. we also update Folder name [(folder As String)] to the new folder
       End If
       File.Delete(folder, f) ' in the second run this LINE will not be called, because we have exit the loop, so when will this line called and delete the folder with the OLD folder name??
   Next

End Sub
[/CODE]

it seems to me like by calling again the event we are NOT exiting the run and we are running the event myltiple time at the same time with different values (folder As String) is this correct?

i hope i was clear
 

DonManfred

Expert
Licensed User
Longtime User
what will happen?
all files and folder get listed from c:\music
- it finds the folder hip hop
- It recursively start the sub again with the folder hip hop as startfolde
- the files in hip hop are deleted. hiphop1, 2 and 3
- it returns to the outer loop of music
- it deletes the folder hiphop
- it finds the folder rock
- It recursively start the sub again with the folder rock as startfolde
- the files in rock are deleted. rock1, 2 and 3
- it returns to the outer loop of music
- it deletes the folder rock
- it finds the folder country
- It recursively start the sub again with the folder country as startfolde
- the files in country are deleted. country1, 2 and 3
- it returns to the outer loop of music
- it deletes the folder country
hip hop\
hiphop1
hiphop2
hiphop3
rock\
rock1
rock2
rock3
country\
country1
country2
country3
 

LucaMs

Expert
Licensed User
Longtime User
To understand code like that, especially recursive routines, debug it step by step (set a breakpoint, run and then press F8), checking the values (or use logs).

For recursive routine, a good debug could be to use an "external variable" (global variable) to store and log the level and the parameters.
B4X:
' Globals
Private mLevel As Int


Sub DeleteFolder (folder As String)
    Log($"Level: ${mLevel} - Folder: ${folder}"$)
    For Each f As String In File.ListFiles(folder)
        If File.IsDirectory(folder, f) Then
            Log($"${TAB} [${f}] folder"$)
            mLevel = mLevel + 1
            DeleteFolder(File.Combine(folder, f))
        Else
            Log($"${TAB} ${f}"$)
        End If
        File.Delete(folder, f)
    Next
    mLevel = mLevel - 1
End Sub
 

DonManfred

Expert
Licensed User
Longtime User
it seems to me like by calling again the event we are NOT exiting the run and we are running the event myltiple time at the same time with different values (folder As String) is this correct?
Yes. It does not exit the loop. it just holds the actual step until the recursive call ends. The loop is continued then....

The same would work for any number of subfolders inside hiphop, rock, country. Even sub-sub-sub-sub-folders
 
Last edited:

Midimaster

Active Member
Licensed User
As I read from your question you cannot understand how the recursion runs?

Well, if you start the first call it will scan the folder. And when the function hits a sub-folder it does not delete the sub-folder but calls the function "DeleteFolder", which means that this level of recursion is stopped immediately and a new deeper level of the same function is opened.

If this 2nd level function again hits a subfolder it jumps down to the next depth of recursion level. This goes as long as the functions find subfolder. Only when a folder (lets say level 3) has no more subfolders the function start to delete the contained files. Then jumps a level higher, back to the loop where it currently scans the level 2. At first it deletes the now empty folder then scan the other filenames of level 2. When it finds another subfolder it jumps again down to level 3 and returns back to the scanning. All files in this level will be deleted too.

So each jumpback ends with the deleting of the now empty folder. If a filename is no folder it deletes it also. When one folder of level 2 is cleared this way it jumps back to level 1 and deletes this empty level 2 folder. After that it can again find another level 2 folder and the recursion starts again getting deeper an deeper.

If all subfolders in level 1 are empty and deleted (and also the files in the root folder) it jumps back to the very first called function and now deletes the (meanwhile empty) root folder.
 
Top