Using FolderItem Count and coursing through FolderItem's directory

I would like to course through a folder to see if a name is matched and then assign it to a folderitem.

I cannot use this code as the analyzer says the folderItem is not an array.

Var fSerch As String//the name being searched for
Var foldr, itemF As FolderItem//foldr is assigned the matched name from the array.
//itemF is the directory

fcnt = itemF.Count
For i = 0 To fcnt
  If fSerch = itemF(i).Name And itemF(i).isFolder Then
    foldr = itemF(i)
    Return 0
  End If
Next

What is the correct code for replacing itemF(i)

See ChildAt in FolderItem class.

Edited:
I have to ask because AutoFill approved the other.
So this is correct way?

itemF.ChildAt(i).isFolder

BTW the analyzer approves

Edit is here: I just learned Count is only about Folders and not Files.
I also screwed up because I had this

itemF(i).isFolder

in the if statement. It should have been itemF(i).isFolder = False

This is the code I needed and is basically in FolderItem.Remove

Var itemF, item, foldr As FolderItem
For Each item In itemF.Children
  If fSerch = item.Name And item.isFolder = False Then
    foldr = item
  End If
Next

So, is there anyway by XOJO’s folderItem’s methods of getting a count of files and folders in a folder?

See count property.

I used count and it reported 12 and I was confused because I didn’t think there were that many of. I counted and I had 12 folders and 5 files. I reread the LR and it had “directory/folder”. Count was correct but it doesn’t include files. Annoying
and I don’t understand why that would be there without a complement for files

What is says is that if you FolderItem is a directory/folder, it is the number of items in that FolderItem. This will not include nested children; it may include non-visible items. Each “item” may be another directory/folder or may be a file. You don’t need a property which reports the count of files. If any items are a subfolder, you do need to recursively count as deep as the nesting goes if you want the total file count across the total depth.

If you counted 12 folders and Count reported 12, then my SWAG is the 5 files you refer to are children in one or more of the 12 folders?

If your folders are very big, you can get massively better performance using FileListMBS and they even have an example program that demonstrates recursion.

1 Like

Apologies. The count was correct at 21 (1 hidden, 15 folders, 5 files)
I may look at MBS

Why don’t you simply try to access it directly?

Var MyItem As FolderItem=ParentFolder.Child(NameOfItem)

if MyItem=nil or not MyItem.Exists then MessageBox "The item doesn't exist."
1 Like

I was trying to avoid that because I am trying avoid accessing properties.
https://forum.xojo.com/t/problems-with-ownerread/66212 is in the Mac OS section. For some reason Apple has decided to flag the application(I Think) that repeatedly tests media file properties. Once it is flagged, any mass search for file property’s doesn’t return true, including even the name. I learned this with this experiment. Grumble.
I had no clue I was going down that path, because FolderItem.Exists worked, until I hit a wall.
Now I have to do OpenFileDialog on each file for which has been flagged.

Your conclusion isn’t clear in the thread you’re referring to. Did you find more information yourself later, not written there?

Another thing that comes to mind: I would expect iterating through a given folder can be done without triggering this flag (in other words, I may understand why Mac OS prevents repeating the same access too many times (security), but iterating to list files has nothing to do with “flooding”).
Is Xojo perhaps checking too many, unneeded, properties of folderitems when iterating? Perhaps it’s gathering all properties before they are even accessed by code, and accessing them only on-demand would resolve this issue?

I believe just iterating is fine, as long as I don’t check anything, including a name.

I suppose I can ask tech support about this.

Feedback filed

<https://xojo.com/issue/66407>

I used Microsoft Edge and Bing Chat and after many failed attempts, came up with the following code. I have to check that it correctly recurses subfolders of the chosen directory, but thought others might find it helpful.

Var cwd As FolderItem = FolderItem.ShowSelectFolderDialog
MessageBox("Current working directory is " + cwd.DisplayName)

Var subdirs() As FolderItem ’ Declare an array of FolderItem objects to store the subdirectories

’ Iterate over the children of the current working directory using a For loop
For i As Integer = 1 To cwd.Count ’ Loop from 1 to the number of children
Var child As FolderItem = cwd.Item(i) ’ Get the child at the current index as a FolderItem object
subdirs.AddRow(child) ’ Add the child to the subdirs array using the AddRow method
Next

Var totalFiles As Integer = 0 ’ Declare an integer variable to store the total number of files

’ Iterate over the elements of the subdirs array using a For Each loop
For Each dirpath As FolderItem In subdirs
If dirpath.Directory Then ’ Check if the current element is a directory using the Directory property
Var file_paths() As FolderItem ’ Declare an array of FolderItem objects to store the files in the current directory
For i As Integer = 1 To dirpath.Count ’ Loop from 1 to the number of children in the current directory
Var child As FolderItem = dirpath.Item(i) ’ Get the child at the current index as a FolderItem object
file_paths.AddRow(child) ’ Add the child to the file_paths array using the AddRow method
Next
’ Iterate over the elements of the file_paths array using a For Each loop
For Each fp As FolderItem In file_paths
If Not fp.Directory Then ’ Check if the current element is a file using the Directory property
totalFiles = totalFiles + 1 ’ Increment the totalFiles variable to count the number of files
End If
Next
End If
Next

MessageBox("Total number of files: " + totalFiles.ToText) ’ Display the total number of files using a MessageBox and converting the integer to text using the ToText method

FWIW, I’ve found that the file recursion in the Chilkat plugin works a lot faster than doing it with folderitems and it may work around this issue. The DirTree plugin is free to use without purchasing a license.

Some example code using the plugin.

I found a better way to do this. The code I wrote seems to fail to count all the files in subdirectories of subdirectories. The following code works better:

Var sh As New Shell
sh.ExecuteMode = Shell.ExecuteModes.Synchronous
sh.Execute("find /Users/phil/Documents/LeapData -type f | wc -l ")
Var result As String = sh.Result
MessageBox("Total number of files in Leapdata subdirectory is " + result)

Instead of hard coding the subdirectory, one could use

Var cwd As FolderItem = FolderItem.ShowSelectFolderDialog

to get the details of the current directory and then plug it into the shell command:

Var cwd As FolderItem = FolderItem.ShowSelectFolderDialog
Var cwdpath As String = cwd.NativePath
Var sh As New Shell
sh.ExecuteMode = Shell.ExecuteModes.Synchronous
'sh.Execute("find /Users/phil/Documents/LeapData -type f | wc -l ")
sh.Execute("find " +cwdpath + " -type f | wc -l ")

Var result As String = sh.Result
MessageBox(“Total number of files in” + cwdpath + " and subdirectories is " + result)