Page 1 of 1

GetFiles()

Posted: Sun Jun 26, 2016 2:42 pm
by Lunasole
Looks like there should be nice collection of file enumerating bicycles ^^
http://www.purebasic.fr/english/viewtop ... 12&t=65963 by @Thunder93
http://www.purebasic.fr/english/viewtop ... 12&t=51878 by @idle

I'll add one more.

I didn't tested this on Linux, also It is based on PB functions, so currently lacks of symbolic links support, but in other aspects should be nice.

// updated replacing array by map and more other stuff added

Code: Select all

EnableExplicit

; enumerates files within given folder (or it's subfolders too)
; Files$			output
; Filter$			a mask to filter files by extensions, separated using "|". example: "txt|jpg", "bmp". empty string used to find all files
; IgnoredPaths$ 	a list of folders to skip on scan. full paths expected, terminated with "\" and separated using "|"
; ScanDeepth 		"-1" = unlimited, "0" = scan only specified folder, "1+" = custom
; GetFolders:		if True, includes also found folders to results. folder paths ending with "\", unlike file paths
; RETURN: 			number of files found; 
; 					Files() values containing full paths
;					Files() keys containing relative paths
Procedure GetFiles (Path$, Map Files$ (), Filter$ = "", IgnoredPaths$ = "", ScanDeepth = 0, GetFolders = #False)
	Static Deepth  			; Current recursion Deepth
	Static RootPathX		; An offset to extract current relative path
	If Not Deepth
		If Filter$ : Filter$ + "|" : EndIf ; force filters termination
		If IgnoredPaths$ : IgnoredPaths$ + "|" : EndIf
		If Not (Right(Path$, 1)) = "\" : Path$ + "\" : EndIf ; path termination
		RootPathX = Len(Path$) + 1 ; if +1 removed, map keys will start with "\"
		ClearMap(Files$())
	EndIf
	
	Protected HDir = ExamineDirectory(#PB_Any, Path$, "*.*")
	Protected Current$
	If HDir
		Deepth + 1
		While NextDirectoryEntry(HDir)         ; iterate all files within directory
			Current$ = DirectoryEntryName(HDir); store current file/folder name for future
			If DirectoryEntryType(HDir) = #PB_DirectoryEntry_File ; enumerate files only
				If PeekC(@Filter$) = 0 Or FindString(Filter$, GetExtensionPart(Current$) + "|", 1, #PB_String_NoCase)
					Current$ = Path$ + Current$
					Files$(Mid(Current$, RootPathX)) = Current$ ; store paths
				Else
					; skip this file
				EndIf
			ElseIf DirectoryEntryType(HDir) = #PB_DirectoryEntry_Directory 
				If ScanDeepth = -1 Or Deepth <= ScanDeepth; check recursion deepth
					If Not Current$ = "." And Not Current$ = ".."
						Current$ = Path$ + Current$ + "\"
						If PeekC(@IgnoredPaths$) And FindString(IgnoredPaths$, Current$ + "|", 1, #PB_String_NoCase)
							; skip this subfolder   
						Else
							If GetFolders ; add folders to results too
								Files$(Mid(Current$, RootPathX)) = Current$ ; store paths
							EndIf
							GetFiles (Current$, Files$(), Filter$, IgnoredPaths$, ScanDeepth, GetFolders) ; go on with subfolders
						EndIf
					EndIf
				EndIf
			EndIf
		Wend
		FinishDirectory(HDir)
		Deepth - 1
		If Not Deepth And MapSize(Files$()) > Deepth ; proceed return only from first level
			ProcedureReturn MapSize(Files$())
		EndIf
	EndIf
EndProcedure


; usage
NewMap Test$()
Debug GetFiles("C:\Documents and Settings", Test$(), "","",1)

Define A
ForEach Test$()
	Debug MapKey(Test$())
	Debug Test$()
	Debug "---"
	A + 1
Next
Debug A

PS. Damnit, forum still breaks code formatted with real TABs :3

Re: GetFiles()

Posted: Tue Sep 27, 2016 10:35 pm
by Lunasole
Here is some modified variant, it uses map instead of array (map can be easily switched to a list. if needed features like result sorting) and allows to include folder paths into results too.
And of course map keys can be adjusted and used later to quickly and easily pick file from results (that's advantage against array or list)

// updated code in the 1st post

Re: GetFiles()

Posted: Wed Sep 28, 2016 7:25 am
by ts-soft

Code: Select all

ReplaceString (Path$, "/", "\", #PB_String_InPlace)
You should not do this on linux. Backslash is part of filename, not path.

Greetings
Thomas

Re: GetFiles()

Posted: Thu Sep 29, 2016 4:22 am
by Lunasole
ts-soft wrote:

Code: Select all

ReplaceString (Path$, "/", "\", #PB_String_InPlace)
You should not do this on linux. Backslash is part of filename, not path.

Greetings
Thomas
Hm, that code remains from older versions of this function and looks like it is not needed here anymore. Thanks, I've missed to remove it.