Define snapshot, imo not possible or workable since things may change constantly.
In Explorer the folders are added to a node on expand.
Enumeration is fast due the fact of caching, if not cached you'll notice.
Sometimes it is slower isn't?
However that cache is not related to controls like in the Explorer, it's the filesystem.
The folderview (Explorer) will avoid holding items in memory since it has no use except what is currently required to have like the 'friendly name' for a folder.
Folders are pidls and you should not take it out of perspective, i mean enumming via a dir$ is just a secundairy method.
Windows folders are more com based as you may think.
Therefore these relative folders like the desktop and my documents etc.
These are namespaces.
I find pidls rather difficult, relative, not relative but the fastest way to obtain foldernames and attributes is through com.
Announcement
Collapse
No announcement yet.
Listing SubFolders in 10 lines of code
Collapse
X
-
>On specific event it add's or deletes an item.
That's just like Win32(SDK): Internet Cookie Monitor April 25, 2001 works.
On the Change event notification, you do a TreeView_InsertItem. YOU do it.
But I suppose you could ....
Code:Lock out all other processes (yes, doable) Get the count of subfolders Set up change notification event Free up other processes
Then you only have uncertainty about what users on OTHER computers do to shared drives whilst processes in THIS computer are locked.
Better I think to 'size as you go.' If the data are changing that much/that often, the best you can do is a 'snapshot' anyway.
MCM
Leave a comment:
-
>With a treeview control, that can't happen... you can count the number of items in the control any time and know it won't change until YOU make it change.
Not sure what you mean but during population of a node (folder) you get a list (if done via com) and if you do it right you watch for a specific event related to folder or file removal.
This is how Windows Explorer works.
On specific event it add's or deletes an item.
Leave a comment:
-
What would be really helpful would be an API that can gives me the number of subfolders a folder has - just like a TreeView control can tell me how many items it has.
Anyone heard of such an API?
With a treeview control, that can't happen... you can count the number of items in the control any time and know it won't change until YOU make it change.
MCM
Leave a comment:
-
From experiance:
Ordinary enums like these are terribly slow.
And i don't mean the redim's but the actual reading.
And there is only one solution, through com.
Yes, pidl's and other terrible stuff.
Leave a comment:
-
I hate the part where making an algorithm safe takes more lines of code than the algorithm itself!
Leave a comment:
-
What would be really helpful would be an API that can gives me the number of subfolders a folder has - just like a TreeView control can tell me how many items it has. Even if I could only get the number of subfolders on a drive, that would be better than guessing.
Anyone heard of such an API?
Leave a comment:
-
Hi Joe,
Yes, that's a good reminder. I actually got the PDF a few times when I was testing the code and realized that my array dimension was the cause.
I hate the part where making an algorithm safe takes more lines of code than the algorithm itself!
Leave a comment:
-
Gary,
One of those things you *might* want to consider is the potential GPF if the number of folders/items exceeds your initial array bounds (>10,000 in this case). Here's a trick many have used in the past to avoid this kind of thing.
Code:While Len(temp$) Incr FolderCount [COLOR="DarkRed"][b]IF FolderCount > UBOUND(Folder()) THEN REDIM PRESERVE Folder(FolderCount + 100) END IF[/b][/COLOR] Folder(FolderCount) = Build$(Folder(iPos),"\",temp$) temp$ = Dir$ (Next) Wend
Leave a comment:
-
Listing SubFolders in 10 lines of code
I was reading several of the threads on listing subdirectories and the code struck me as perhaps more complicated than I wanted it to be.
So I wrote a non-recursive, 10-line subroutine that will create the listing (ok, there's also a couple of DIM lines, too, including a Global array where the results are stored).
Code:Sub ListSubFolders(startfolder$) 'Start$ cannot end in \ 'returns list of folder (full paths) in Folder() - unsorted Dim iPOS As Long Folder(FolderCount) = startfolder$ While Len(Folder(iPOS)) temp$ = Dir$(Build$(Folder(iPOS),"\*.*"), Only %SubDir) 'subfolders only While Len(temp$) Incr FolderCount Folder(FolderCount) = Build$(Folder(iPos),"\",temp$) temp$ = Dir$ (Next) Wend Incr iPOS Wend End Sub
Code:temp$ = Dir$(Build$(Folder(iPOS),"\*.*"), %SubDir) 'subfolders + files
As a minimalist kind of programmer, I like the compactness - not to mention how easy it is to understand.
On small directory structures it's very fast - basically instant response. On a full c-drive it took about 1 minute to read about 10,000 subfolders. I don't know enough about DIR$ to know whether the number of files matters in how fast it works, or if just the number of subfolders is the determining factor.
I keep meaning to copy one of the recursive versions and do a speed comparison.
Once the code is used, Window keeps all of the directory info in a cache, so doing tests means I have to reboot or, if I knew how, clear the cache to get valid answers. Does anyone know an easy way to clear the cache so subsequent runs of the code won't give wrong answers (basically instant response for an entire drive).
I don't do subfolder listings all that often so I've not given much thought on how to speed this up. I assume there is an API that DIR$ draws on. Would that speed this up significantly?
Below is a complete PowerBASIC app that puts the results into a listbox.
Note that I dimensioned the array to hold 10,000 subfolders. To list files, a much larger array is needed. Also, the subroutine returns the list unsorted. In this example, the listbox sorts it, but I could have used ARRAY SORT.
Another trick I used is to create the listbox after the list array was created. That way I can load an entire array of data in one statement. That brings up a question - can I load an array to a listbox, adding the array content to what is already in the listbox? Help doesn't say I can.
Code:#Compile Exe Global hDlg As Dword Global Folder() As String, FolderCount As Long Function PBMain() As Long Dialog New Pixels, 0, "ListBox Test",300,100,230,300, _ %WS_OverlappedWindow, 0 To hDlg Control Add Button, hDlg, 100,"Start Search", 10,10,100,20 Control Add Label, hDlg, 150,"", 120,10,100,20, %WS_Border Or %SS_Center Dialog Show Modal hDlg Call DlgProc End Function CallBack Function DlgProc() As Long If Cb.Msg = %WM_Command And Cb.Ctl = 100 And Cb.CtlMsg = %BN_Clicked Then Dim Folder(10000) ListSubFolders("d:\temp") ReDim Preserve Folder(FolderCount) Control Add ListBox, hDlg, 200, Folder(), 10,40,210,250 Control Set Text hDlg, 150, Str$(FolderCount+1) End If End Function Sub ListSubFolders(startfolder$) 'Start$ cannot end in \ 'returns list of folder (full paths) in Folder() - unsorted Dim iPOS As Long Folder(FolderCount) = startfolder$ While Len(Folder(iPOS)) temp$ = Dir$(Build$(Folder(iPOS),"\*.*"), Only %SubDir) 'subfolders only While Len(temp$) Incr FolderCount Folder(FolderCount) = Build$(Folder(iPos),"\",temp$) temp$ = Dir$ (Next) Wend Incr iPOS Wend End Sub
Last edited by Gary Beene; 17 Feb 2009, 10:07 AM.Tags: None
Leave a comment: