Exiting a series of nested If...end if and For...Next loops

I am in the processing of building a Mac app for searching the entire hard drive or individually identified folders. I have success with the tool when pointing it at a specific folder such as the Desktop/Documents/Downloads folders. However, if I point it at the User profile, the search goes into an infinite loop and I am not sure how to fix it. Any help would be greatly appreciated. Below is my code:

[code]Dim file, path, sourcefile, splitfilename As String

if f<>nil then
if f.Directory then
if NOT f.isBundleMBS Then

for i as Integer=1 to f.Count
file = f.Item(i).Name
path = f.DisplayPathMBS
currentFileLabel.Text = f.Item(i).NativePath

if NOT f.isApplicationMBS Then
SearchFiles(f.Item(i))

filesplit.Append file
dim splitfiles() As String = Split(filesplit.Pop.ToText, “.”)

App.DoEvents

for ii as integer = 0 to splitfiles.Ubound
splitfilename = splitfiles(ii)

for iii as Integer = 0 to filenames.Ubound
sourcefile = filenames(iii)

if sourcefile = splitfilename Then

List.AddRow file
List.Cell(List.LastIndex,1) = format(f.Item(i).LogicalFileDataLengthMBS/1024,“0”)+" KB"
List.Cell(List.LastIndex,2) = str(f.Item(i).CreationDate)
List.Cell(List.LastIndex,3) = str(f.Item(i).ModificationDate)
List.Cell(List.LastIndex,4) = " — "
List.Cell(List.LastIndex,5) = “/Volumes/” + f.Item(i).DisplayPathMBS

end if
next
next
end if
next
end if
end if
end if[/code]

Is this a console app? Because the first thing people will tell you to do is
Nevermind, I see that you are clearly using UI stuff - so this must be a desktop app.

Get rid of App.doEvents. Why is it even there?

What does the searchFiles() method do? Is that the method you sent the code for? i.e., is this a recursive function?
Does f.item() ever return the current and / or the parent directory? (. and … ) - if this is recursive, and it DOES return the current directory, a brief scan of your code looks like it will sit there looking at the current directory forever.

But seriously, get rid of app.doEvents. Bad mojo there.

This is not a console app. I am using App.DoEvents now just to get viewable results.

The code I sent is for the SearchFiles method and it is a recursive function. How would I go about getting it to return the current/parent directory.

What’s weird, as I stated earlier, is if I point it at my Desktop folder, which has many folders/subfolders on it, the recursion works fine and ends when it is done. It seems to be an issue when I point it at the User profile and that is when I get the infinite loop.

Thoughts??

You need to make this event driven, App.DoEvents is a bad idea. Whenever you think you need it put a dollar in the jar.
Unfortunately, file actions in Xojo are blocking, so threading won’t help.

You’re already using MBS so you should try switching to the MBS file functions as you’ll get faster and better results.

Ok. I will take a look at the MBS file functions.

Also, get familiar with system.deubugLog(), and use it as you walk the file tree to see a) where you are and b) how is your function recursing.

I plunked your code into a new project, massaged it a bit to remove app.doEvents and give it the arrays you are using, and remove the bit that looks for file names to match etc, then pointed it to a folder that is a subfolder of my desktop to see where it traverses. It worked fine. @Tim Parnell is right - this is a slow approach, but it does work.

But seriously: STOP USING APP.DOEVENTS. It is NOT safe to use at all in desktop apps.

Here’s your massaged code that seems to work for me:
https://s3.amazonaws.com/downloads.miridiatech.com/temp/RecursiveFileSearch.zip

Kimball,

I downloaded your massaged version. I ran it against a standard folder/subfolders and files and it worked great. However, when I pointed it to my User profile, it again got caught in an infinite loop. How do I stop this from happening???

When running my version, in Xojo, click on the messages pane at the bottom of the run window (far right icon in the little group of 3 at the bottom of the xojo window when running the app in the debugger).

When I run it against my user directory, it appears to be running just fine, but my user directory has about 600 GB of data in it, and I’m not really ready to sit here and wait for it to finish… it’ll take forever. However… it does not appear to be backtracking or behaving badly - just taking a while because there is a lot of data to traverse.

If it’s truly in an infinite loop (and not just taking a long time as Kimball noticed), perhaps user profile tree has a symbolic link that points to a directory that is at a higher leaf in the directory tree? Maybe open a Terminal window and use something like this to find all the symbolic links:

find /Users/user -type l -ls

(replacing /Users/user with the top-level directory of your user profile)

Sample output

4770946        0 lrwxr-xr-x    1 palmered         staff                   8 Jan 24 15:36 foo/bar/baz/boo -> ../../..

If that’s the case, you might want to look into FolderItem.Alias as a way of detecting those and decide how you want to handle them.

I gotcha. My user profile is only 113 GB and I was watching the debugger window as it was running. I kept seeing the same directories getting parsed over and over. I have double-checked and I do not see any alias files redirecting back to those folders or any upper level folders either.

If it is a loop no the file system, try adding the paths into a Xojo Directory as you traverse, breakpoint when you try to add a path that already exists and that should indicate where to look for the issue.

@Roger Martin - you might also want to look at using FolderItem.TrueItem instead of FolderItem.Item as well.

https://documentation.xojo.com/api/files/folderitem.html.TrueItem

@Kimball Larsen — LOL. I don’t know why everyone is so against App.DoEvents. I have never experienced any problem with it in 10+ years, though I understand the concerns and I usually avoid it those days.

A more general advise just for readabillity :slight_smile:

Try to avoid

If ... Then If ... Then If ... Then End If End If End If

Try to do:

[code]If … Then
// A FailState. Do error handling and then Return…
Return
End If

If … Then
// A FailState. Do error handling and then Return…
Return
End If

If … Then
// A FailState. Do error handling and then Return…
Return
End If

// Now do what you really wanted to achive[/code]

You may use exit http://documentation.xojo.com/api/code_execution/exit.html to get out of an infinite loop.

Because it starts a new event loop, and can cause all sorts of funky difficult-to-reproduce bugs. There are certain circumstances where if you know exactly what you are doing and understand the implications, using app.doEvents in a gui app is perfectly safe… but the guidance from Xojo engineering has always been “Don’t. Do. It.”

Quoting from the reference docs: “Using DoEvents in a GUI application will likely cause instability. In effect, you would be placing a main event loop inside the real main event loop.”

thanks Kimball,
I downloaded your RecursiveFileSearch.zip file, had to change it a bit because I’m not using MBS,
works perfect, thanks again

The FolderItem.TrueItem route worked to overcome my infinite looping issue.

https://documentation.xojo.com/api/deprecated/application.html#application-doevents