Listing files in a directory

Just starting out? Need help? Post your questions and find answers here.
User avatar
PureLeo
Enthusiast
Enthusiast
Posts: 221
Joined: Fri Jan 29, 2010 1:05 pm
Location: Brazil

Listing files in a directory

Post by PureLeo »

Hi ppl!

So, I'm making a little app for my own, to help me track my backup DVDs files and stuff...

I've never messed with directories and files very well on Purebasic, so I'm getting a little confused.

How can I list EVERY file in a directory?

Because..

Code: Select all

While NextDirectoryEntry(0)
                    
                    FileName$ = DirectoryEntryName(0)
                    If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory
                      FileName$ = "[DIR] "+FileName$
                    EndIf
                    
                    AddGadgetItem(#Gadget_Form1_List, -1, FileName$)
                    
                  Wend
..doesn't go INSIDE every folder and subfolder to get every item.

I'm sorry if anyone have already posted something about this.. I couldn't find it, only stuff about FTP directories. And I didnt want someone to code it for me, it's just because im getting too confused with how to make it go inside a DIR, get files, get inside a SUBDIR if any, then go back to last DIR, continue from where it stopped, and etc, etc, etc :roll:

If anyone has already done anything like this and is ok with sharing it, it would be awesome :mrgreen:

Thanks in advance!
Leo
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Listing files in a directory

Post by Trond »

Code: Select all


Procedure ListFilesRecursive(Dir.s, List Files.s())
  NewList Directories.s()
  If Right(Dir, 1) <> "\"
    Dir + "\"
  EndIf
  D = ExamineDirectory(#PB_Any, Dir, "")
  While NextDirectoryEntry(D)
    Select DirectoryEntryType(D)
      Case #PB_DirectoryEntry_File
        AddElement(Files())
        Files() = Dir + DirectoryEntryName(D)
      Case #PB_DirectoryEntry_Directory
        Select DirectoryEntryName(D)
          Case ".", ".."
            Continue
          Default
            AddElement(Directories())
            Directories() = Dir + DirectoryEntryName(D)
        EndSelect
    EndSelect
  Wend
  FinishDirectory(D)
  ForEach Directories()
    ListFilesRecursive(Directories(), Files())
  Next
EndProcedure

NewList F.s()
ListFilesRecursive("C:\Documents and Settings\Trond\My Documents\Docs\htdocs\eegallery\", F())
ForEach F()
  Debug F()
Next

User avatar
PureLeo
Enthusiast
Enthusiast
Posts: 221
Joined: Fri Jan 29, 2010 1:05 pm
Location: Brazil

Re: Listing files in a directory

Post by PureLeo »

Yes!
Exactly!

Thanks Trond :mrgreen:
User avatar
Lewis
User
User
Posts: 47
Joined: Fri Nov 25, 2005 1:12 pm

Re: Listing files in a directory

Post by Lewis »

Hmmm... I use the shell and DOS commands to change directory and list to a textfile, namely

1. Open up your command prompt by typing cmd in the run dialog box and hitting Enter.
2. Navigate to the directory which has the files and type the following command -- DIR /B /O:N > filename.txt
This will save all the filenames in the current directory to a text file. The text file will be saved in the same directory.
3. To save file names from any sub-directories in the current folder, just add /S like -- DIR /B /O:N /S > filename.txt

I found these instructions on the web.;)

However, has anyone made a standalone (in PB) that uses an Explorer folder tree to list folder contents to either clipboard or textfile (or both)? Surely such an app would be more user-friendly than using the shell/command prompt?
heinz
New User
New User
Posts: 3
Joined: Sat Jan 08, 2011 10:15 am

Re: Listing files in a directory

Post by heinz »

Code: Select all

; English forum: http://www.purebasic.fr/english/viewtopic.php?t=6064&highlight=
; Author: Fangbeast (updated for PB4.00 by blbltheworm)
; Date: 05. May 2003
; OS: Windows
; Demo: No
 
#Tree = 1 
#List = 2 
#Text = 3 

#folder = 4 
#drive = 5 
#imail = 6 
; 
Global fver.s,fid0.s,fname.s,ftype.s,fcat.s,fcoll.s,fdisp.s,tmark.s,tlink.s,fid1.s,fid2.s,fid3.s,fid4.s,fid5.s 
; 
Declare DirScan(DirectoryID.l, DirectoryName.s) 
Declare FileScan(FilePath.s) 
Declare ProcessFile(FileInfo.s) 
Declare.s GetIni(key.s, section.s)                          ; Get data from content.ini file 
; 
Global NewList FullPaths.s() 
; 
OpenWindow(0, 0, 0, 800, 600, "Dir Scan...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
;CreateGadgetList(WindowID(0)) 
TreeGadget(#Tree,  10,  10, 180, 530, #PB_Tree_AlwaysShowSelection) 
ListIconGadget(#List, 200, 10, 590, 530, "File", 150, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 
  AddGadgetColumn(#List, 1, "Size", 50) 
  AddGadgetColumn(#List, 2, "Attr", 50) 
  AddGadgetColumn(#List, 3, "Type", 80) 
  AddGadgetColumn(#List, 4, "Cat",  80) 
  AddGadgetColumn(#List, 5, "Col", 80) 

TextGadget(#Text,  10, 550, 770,  40, "", #PB_Text_Border) 
; 
AddGadgetItem(#Tree, -1, "C:", 0) : DirScan(0, "C:\") 
AddGadgetItem(#Tree, -1, "D:", 0) : DirScan(0, "D:\") 
AddGadgetItem(#Tree, -1, "E:", 0) : DirScan(0, "E:\") 
; 
SetGadgetItemState(#Tree, 0, #PB_Tree_Expanded | #PB_Tree_Selected) 
  SelectElement(FullPaths(), 0) 
  FileScan(FullPaths()) 
; 
Repeat 
  EventID = WaitWindowEvent() 
    If EventID = #PB_Event_Gadget 
      Select EventGadget() 
        Case #Tree  : Gosub TreeClicked 
      EndSelect 
    EndIf 
Until EventID = #PB_Event_CloseWindow 
End 
; 
TreeClicked: 
  If EventType() = #PB_EventType_LeftClick And GetGadgetState(#Tree) <> -1 
   ; ClearGadgetItemList(#List) 
    CurrentLine = GetGadgetState(#Tree) 
    SelectElement(FullPaths(), CurrentLine) 
    FileScan(FullPaths()) 
  EndIf 
Return 
; 
Procedure DirScan(DirectoryID.l, DirectoryName.s) 
  AddElement(FullPaths()) 
  FullPaths() = DirectoryName 
  SetGadgetText(#Text, DirectoryName) 
  
  
  ;OpenTreeGadgetNode(#Tree) 
  If ExamineDirectory(DirectoryID, DirectoryName, "*.*") 
    Repeat 
      entry.l = NextDirectoryEntry(DirectoryID) 
      If entry = 1  
        AddGadgetItem(#Tree, -1, DirectoryEntryName(DirectoryID),0,1) ;(FileName found) 
      ElseIf entry = 2 
        name.s = DirectoryEntryName(DirectoryID) 
        If name <> "." And name <> ".." 
          While WindowEvent():Wend 
          AddGadgetItem(#Tree, -1, name, 0) 
          DirScan(DirectoryID + 1, DirectoryName + name + "\") 
        EndIf 
      EndIf 
    Until entry = 0 
  EndIf 
  ;CloseTreeGadgetNode(#Tree) 
EndProcedure 
; 
Procedure FileScan(FilePath.s) 
  If ExamineDirectory(1024, FilePath.s, "*.*") 
    Repeat 
      FileType     = NextDirectoryEntry(1024) 
      FileName.s   = DirectoryEntryName(1024) 
      FileSize     = FileSize(FilePath.s + "\" + DirectoryEntryName(1024)) 
      Mattribute   = DirectoryEntryAttributes(1024) 
      LetrType.s   = UCase(Right(FileName, 4)) 

      If Mattribute & #PB_FileSystem_Normal         : Attributes.s = "-----" 
      ElseIf Mattribute & #PB_FileSystem_ReadOnly   : Attributes.s = "R----" 
      ElseIf Mattribute & #PB_FileSystem_Archive    : Attributes.s = "-A---" 
      ElseIf Mattribute & #PB_FileSystem_System     : Attributes.s = "--S--" 
      ElseIf Mattribute & #PB_FileSystem_Hidden     : Attributes.s = "---H-" 
      ElseIf Mattribute & #PB_FileSystem_Compressed : Attributes.s = "----C" 
      EndIf 

;      Select LetrType 
;        Case ".IMF" : ProcessFile(FilePath.s + "\" + FileName.s) 
;        Case ".IMA" : ProcessFile(FilePath.s + "\" + FileName.s) 
;        Case ".IME" : ProcessFile(FilePath.s + "\" + FileName.s) 
;        Case ".IMI" : ProcessFile(FilePath.s + "\" + FileName.s) 
;        Case ".IMN" : ProcessFile(FilePath.s + "\" + FileName.s) 
;        Case ".IMS" : ProcessFile(FilePath.s + "\" + FileName.s) 
;        Case ".IMW" : ProcessFile(FilePath.s + "\" + FileName.s) 
;        Default     : ftype.s = ""  : fcat.s = "" : fcoll.s = "" 
;      EndSelect 
      
      If FileType = 1 
        While WindowEvent():Wend 
        AddGadgetItem(#List, -1, FileName.s + Chr(10) + Str(FileSize) + Chr(10) + Attributes + Chr(10) + ftype.s + Chr(10) + fcat.s + Chr(10) + fcoll.s) 
      EndIf 
    Until FileType = 0 
  EndIf 
EndProcedure 
; 
; Process the files found during the directory search 
; 

Procedure ProcessFile(FileInfo.s) 

  If ReadFile(0, FileInfo.s) 
    ; 
    unpacker.s = "C:\iCat2\cabarc.exe"                        ; Drive and directory for extract.exe 
    params.s = " -o x " + Chr(34) + FileInfo.s + Chr(34) + " content.ini C:\iCat2\" 

    If RunProgram(unpacker.s, params.s, "", 1 | 2) <> 0 
    EndIf 

    section.s   = "Version" 
      fver.s    = GetIni("Number", section.s) 
    section.s   = "General" 
      fid0.s    = GetIni("ID", section.s) 
      fname.s   = GetIni("File", section.s) 
      ftype.s   = GetIni("Type", section.s) 
      fcat.s    = GetIni("Category", section.s) 
      fcoll.s   = GetIni("Collection", section.s) 
      fdisp.s   = GetIni("Display", section.s) 
    section.s   = "Trademark" 
      tmark.s   = GetIni("TradeMark", section.s) 
    section.s   = "X-Extensions" 
      tlink.s   = GetIni("TradeMarkLink", section.s) 
    section.s   = "Depend" 
      fid1.s    = GetIni("id0", section.s) 
      fid2.s    = GetIni("id1", section.s) 
      fid3.s    = GetIni("id2", section.s) 
      fid4.s    = GetIni("id3", section.s) 
      fid5.s    = GetIni("id4", section.s) 

  DeleteFile("C:\iCat2\content.ini") 
  
  EndIf 

EndProcedure 

; API procedure for INI file reading 

Procedure.s GetIni(key.s, section.s)                                            ; Procedure returns a string 

  Empty.s = ""                                                                   ; Default value if nothing found 
  ReturnSpace.s = Space(255)                                                     ; Make sure the variable has plenty of room 
  IniData = GetPrivateProfileString_(section.s, key.s, Empty.s, @ReturnSpace.s, 255, "C:\iCat2\content.ini") 
  
  ProcedureReturn ReturnSpace.s                                                ; Return the data to the calling line 

EndProcedure 

;DataSection 
;folder: IncludeBinary "..\..\Graphics\Gfx\Folder.ico" 
;  drive:  IncludeBinary "..\..\Graphics\Gfx\Disk.ico" 
;  imail:  IncludeBinary "..\..\Graphics\Gfx\Mail.ico" 
;EndDataSection 
heinz
New User
New User
Posts: 3
Joined: Sat Jan 08, 2011 10:15 am

Re: Listing files in a directory

Post by heinz »

This displays files and folders in a tree gadget

Code: Select all

Global dirlevel.b

Procedure ScanPath(Path.s) 
  Protected dir.l, name.s, files.l
  Dirlevel = Dirlevel + 1
  dir = ExamineDirectory(#PB_Any, Path, "")
  If dir
    While NextDirectoryEntry(dir)
      name = DirectoryEntryName(dir)
      If DirectoryEntryType(dir) = #PB_DirectoryEntry_File      
          files + 1
          AddGadgetItem(0, -1, name + "  -  " + Str(DirectoryEntrySize(dir)) ,0 , Dirlevel )
      EndIf
    Wend
    FinishDirectory(dir)
  EndIf
  
  dir = ExamineDirectory(#PB_Any, Path, "")
  If dir
    While NextDirectoryEntry(dir)
      name = DirectoryEntryName(dir)
      If name <> "." And name <> ".." And DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory
          AddGadgetItem(0, -1, name ,0 , Dirlevel)
          files + ScanPath(Path + name + "\")
      EndIf
    Wend 
    FinishDirectory(dir)
  EndIf
  Dirlevel = Dirlevel - 1
  ProcedureReturn files
EndProcedure

OpenWindow(0, 0, 0, 600, 600, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
TreeGadget(0, 10, 10, 580, 580)      
AddGadgetItem(0, -1, "c:\" ,0 , 0)
Debug ScanPath("c:\")

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Listing files in a directory

Post by TerryHough »

heinz wrote:This displays files and folders in a tree gadget
Your code isn't recursive. It only lists the files and sub-folder names of the examined directory in the tree. Any files or sub-folders in sub-folders will not be shown.

This example code is an example of a recursively examined directory displayed in a tree gadget.

Code: Select all

; Example of a recursively examined directory displayed in a tree gadget - TerryHough
;
Enumeration
  #Tree_Gadget
EndEnumeration
  
Procedure TreeExamineDirectory(SourceDirectory$, DirLevel.l = 0)
  Static Count.l
  If ExamineDirectory(DirLevel, SourceDirectory$, "*.*")
    AddGadgetItem(#Tree_Gadget, -1, SourceDirectory$, 0, DirLevel)
    While NextDirectoryEntry(DirLevel)
      Select DirectoryEntryType(DirLevel)
        Case #PB_DirectoryEntry_Directory
          If DirectoryEntryName(DirLevel) <> "." And DirectoryEntryName(DirLevel) <> ".."
            a$ = SourceDirectory$+DirectoryEntryName(DirLevel)+"\"
            DirLevel+1
            TreeExamineDirectory(a$, DirLevel)
            DirLevel-1
          EndIf   
          
        Case #PB_DirectoryEntry_File
          AddGadgetItem(#Tree_Gadget, -1, SourceDirectory$+DirectoryEntryName(DirLevel) + "  -  " + Str(DirectoryEntrySize(DirLevel)) , 0, DirLevel+1)
          Count + 1
          
      EndSelect
    Wend
    FinishDirectory(DirLevel)
  EndIf
  ProcedureReturn Count
EndProcedure

SetCurrentDirectory("C:\PureBasic")

If OpenWindow(0, 0, 0, 400, 200, "Tree Style Recursively Examined Directory", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(#Tree_Gadget, 10, 10, 580, 580)      
  Starttime = ElapsedMilliseconds() ; timer start
  Files.l = TreeExamineDirectory(GetCurrentDirectory())
  Totaltime = ElapsedMilliseconds() - Starttime  ; compute total time for the examine
  SetGadgetItemState(#Tree_Gadget, 0, #PB_Tree_Expanded)    ; expand the tree base 
  ; Optionally, build and display a report message
    Msg$ + #LF$ + Str(Files) + " files selected from target folder" + #LF$ 
    Msg$ + Str(CountGadgetItems(#Tree_Gadget)) + " files & folders shown" + #LF$ 
    Msg$ + Str(Totaltime) + " ms"
    MessageRequester("Examine Results", Msg$ , #MB_ICONINFORMATION) 
  ; end optional report message
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
End 
The following is a similar example using the ExplorerListGadget to do part of the work. I thought it might be a bit quicker, but it is actually much slower. However, it does format the resulting TreeGadget list with all of the sub-folders at the beginning of the list automatically.

Code: Select all

; Example of a recursively explored directory displayed in a tree gadget - TerryHough

Enumeration
  #ExplorerList_Gadget
  #Tree_Gadget
EndEnumeration

Global Msg$ 

Procedure RecursivelyExploreDirectory(SourceDirectory$, DirLevel = 0)
  Static Count  ; must be a static or global variable
  If ExamineDirectory(DirLevel, SourceDirectory$, "*.*")
    AddGadgetItem(#Tree_Gadget,-1,SourceDirectory$, 0, DirLevel)
    While NextDirectoryEntry(DirLevel)
      DirName$ = DirectoryEntryName(DirLevel)
      Select DirectoryEntryType(DirLevel)
        Case #PB_DirectoryEntry_Directory
          If DirectoryEntryName(DirLevel) <> "." And DirectoryEntryName(DirLevel) <> ".."
            a$ = SourceDirectory$+DirectoryEntryName(DirLevel)+"\"
            DirLevel+1
            RecursivelyExploreDirectory(a$, DirLevel)
            DirLevel-1
          EndIf
      EndSelect
    Wend
    FinishDirectory(DirLevel)
    ExplorerListGadget( #ExplorerList_Gadget, 0, 0, 0, 0,  SourceDirectory$ + Pattern$, #PB_Explorer_NoFolders | #PB_Explorer_NoParentFolder)
    ;Do whatever you need to with the contents resulting explorer file list
    If CountGadgetItems(0) > 0
      Count + CountGadgetItems(0) ; increase selected file count
      ;Optionally, report folder results in a message
        Msg$ + SourceDirectory$ + ": " + Str(CountGadgetItems(0)) + " in folder" + " - " + Str(count) + " total files" + #LF$
      ;Optionally, add each selected file To external List
      For K = 0 To CountGadgetItems(0)-1  
        AddGadgetItem(#Tree_Gadget,-1,SourceDirectory$ + GetGadgetItemText(0,k,0), 0, DirLevel+1) ; populate tree gadget
      Next  
    EndIf   
  EndIf
  ProcedureReturn Count
EndProcedure

SetCurrentDirectory("C:\PureBasic\")

If OpenWindow(0, 0, 0, 400, 200, "Recursive Explorer List", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(#Tree_Gadget, 10, 10, 580, 580)      
  Starttime = ElapsedMilliseconds() ; timer start
  Files.l = RecursivelyExploreDirectory(GetCurrentDirectory())
  Totaltime = ElapsedMilliseconds() - Starttime  ; capture operation time
  SetGadgetItemState(#Tree_Gadget, 0, #PB_Tree_Expanded)    ; expand the tree base 
  SetActiveGadget(#Tree_Gadget)
  ; Optionally, build a report message
    Msg$ + #LF$ + Str(Files) + " files selected from target folder" + #LF$ 
    Msg$ + Str(CountGadgetItems(#Tree_Gadget)) + " listed" + #LF$ 
    Msg$ + Str(Totaltime) + " ms"
    MessageRequester("Find Files", Msg$ , #MB_ICONINFORMATION) 
  ; end optional report message
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
End 
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Listing files in a directory

Post by Danilo »

TerryHough wrote:This example code is an example of a recursively examined directory displayed in a tree gadget.
Its very dangerous to do this recursively. If the directories are nested
too deep, your application will crash with stack overflow because on every
recursive call new arguments are put onto the stack.
User avatar
graph100
Enthusiast
Enthusiast
Posts: 115
Joined: Tue Aug 10, 2010 3:17 pm

Re: Listing files in a directory

Post by graph100 »

you can use a recursive trick to avoid that.
You have to use a LinkedList and then to add new directory in it.

Code: Select all

Procedure RecursiveSafe_Directory(path$, List File.s())
	Protected NewList ToDo.s(), hd
	
	If Right(path$, 1) <> "\" : path$ + "\" : EndIf
	
	AddElement(ToDo())
	ToDo() = path$
	
	ResetList(ToDo())
	
	While NextElement(ToDo())
		path$ = ToDo()
		DeleteElement(ToDo())
		
		hd = ExamineDirectory(#PB_Any, path$, "*.*")
		
		If hd
			While NextDirectoryEntry(hd)
				
				If DirectoryEntryType(hd) = #PB_DirectoryEntry_File
					AddElement(File())
					File() = path$ + DirectoryEntryName(hd)
					
				Else
					If DirectoryEntryName(hd) <> "." And DirectoryEntryName(hd) <> ".."
						; ajout du répertoire 
						AddElement(ToDo())
						ToDo() = path$ + DirectoryEntryName(hd) + "\"
						
					EndIf
				EndIf
				
			Wend
			
			FinishDirectory(hd)
		EndIf
		
		ResetList(ToDo())
	Wend
	
EndProcedure

NewList file.s()

RecursiveSafe_Directory("D:\Documents\Programmes Pure\", file())

ForEach file()
	Debug file()
Next
_________________________________________________
My Website : CeriseCode (Warning : perpetual changes & not completed ;))
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Re: Listing files in a directory

Post by TerryHough »

@Danilo
Good to see you on here again..
Danilo wrote:... If the directories are nested too deep, your application will crash with stack overflow ...
You may be correct. But what is "too deep"? How many levels of sub-directories would that be?

I've never experienced a failure with recursion. And, the example I provided has been run thousands of times in one of my FTP programs that is in widespread usage. AFAIK, no one has ever experienced a failure or stack overflow in actual usage.
moogle
Enthusiast
Enthusiast
Posts: 372
Joined: Tue Feb 14, 2006 9:27 pm
Location: London, UK

Re: Listing files in a directory

Post by moogle »

TerryHough wrote:You may be correct. But what is "too deep"? How many levels of sub-directories would that be?

I've never experienced a failure with recursion. And, the example I provided has been run thousands of times in one of my FTP programs that is in widespread usage. AFAIK, no one has ever experienced a failure or stack overflow in actual usage.

Not a lot of people have directories that deep to crash it but the fact remains that it could crash if not limited.
Image
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Listing files in a directory

Post by Danilo »

TerryHough wrote:
Danilo wrote:... If the directories are nested too deep, your application will crash with stack overflow ...
You may be correct. But what is "too deep"? How many levels of sub-directories would that be?

I've never experienced a failure with recursion. And, the example I provided has been run thousands of times in one of my FTP programs that is in widespread usage. AFAIK, no one has ever experienced a failure or stack overflow in actual usage.
It depends on the stack size and how many variables (+return address) are pushed onto
the stack on every recursive call.
After writing the last message i was also thinking more about it. Is it possible to
nest directories that deep?
The thing is, i had this problem some years ago when i scanned my whole c:\ drive
with it. So i wrote something like graph100, eliminating the recursion and it worked
perfectly. Because i always remember this (took some time to find this bug in my code -
it worked ok with many directories but not with deeply nested ones), i never used recursion
again for directory scanning.
Althought your code works here now without crashing. :)
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: Listing files in a directory

Post by kenmo »

Hi PureLeo,

Here's my version of directory scanning: http://www.purebasic.fr/english/viewtop ... 12&t=45905
(You reminded me to post my updated version.)

It's basically the same as these versions, but with some flags and file type filters.

It uses the (dangerous?) recursive method as well, but for what it's worth I have never had a crash yet........
User avatar
graph100
Enthusiast
Enthusiast
Posts: 115
Joined: Tue Aug 10, 2010 3:17 pm

Re: Listing files in a directory

Post by graph100 »

isn't it quicker (if by a little) to eliminate all the procedure call ? And the recursion can take quite some memory.
_________________________________________________
My Website : CeriseCode (Warning : perpetual changes & not completed ;))
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Listing files in a directory

Post by ts-soft »

Here another one. To cancel set the procedurereturn to #False in your Callback (MyFiles() in this example.

Code: Select all

EnableExplicit

Prototype clbSearchFile(lType.l, sName.s)

Procedure BrowseDirectory(sPath.s, *pClbFound = 0)
  Protected lDicID.l, qFiles.q, sDirName.s
  Static pCallBack.clbSearchFile
  
  If (Right(sPath, 1) <> "\"): sPath + "\"  : EndIf
  If (Not pCallBack): pCallBack = *pClbFound: EndIf
  
  lDicID = ExamineDirectory(#PB_Any, sPath, "*.*")
  If lDicID
    While NextDirectoryEntry(lDicID)
      qFiles + 1
      
      If DirectoryEntryType(lDicID) =  #PB_DirectoryEntry_File
        If Not pCallBack(1, sPath + DirectoryEntryName(lDicID))
          Break
        EndIf
        
      Else
        sDirName = DirectoryEntryName(lDicID)
        
        If (sDirName <> ".") And (sDirName <> "..")
          
          If pCallBack(2, sPath + sDirName)   
            qFiles + BrowseDirectory(sPath + sDirName)
          Else
            Break
          EndIf
        EndIf
      EndIf
    Wend

    FinishDirectory(lDicID)
    ProcedureReturn qFiles
  EndIf
EndProcedure

NewList Files.s()

Procedure MyFiles(Type, Name$)
  Shared Files.s()
  If Type = 2
    ProcedureReturn #True
    
  Else
    AddElement(Files())
    Files() = Name$
    ProcedureReturn #True
  EndIf
EndProcedure

Define count, time, time2
time = ElapsedMilliseconds()
count = BrowseDirectory("C:\", @MyFiles()) 
time2 = ElapsedMilliseconds() - time

MessageRequester(Str(count) + "Files", "scanned in: " + Str(time2) + "ms")
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Post Reply