Page 1 of 1

GetFolderSize()

Posted: Thu Feb 21, 2013 10:49 pm
by Rescator
This is a procedure to get the size of a folder and all sub-folders, it is non-recursive (in other words it does not need to call itself to handle sub folders).

Code: Select all

;Public Domain
Procedure.q GetFolderSize(folder$)
	Protected size.q,NewList folders.s(),directory.i,name$,delim$
	If FileSize(folder$)=-2
		CompilerIf #PB_Compiler_OS=#PB_OS_Windows
			delim$="\"
		CompilerElse ;MacOS or Linux
			delim$="/"
		CompilerEndIf
		If Right(folder$,1)<>delim$
			folder$=folder$+delim$ ;make sure the folder name ends with \ (WIndows)  or / (Linux/Mac Os)
		EndIf
		AddElement(folders())
		folders()=folder$ ;add the main folder to the list
		While ListSize(folders())
			folder$=folders()
			DeleteElement(folders(),1) ;remove the folder from the list
			directory=ExamineDirectory(#PB_Any,folder$,"")
			If directory
				While   NextDirectoryEntry(directory)
					If DirectoryEntryType(directory)=#PB_DirectoryEntry_File
						size+DirectoryEntrySize(directory) ;add the entry size to total size so far
					Else
						name$=DirectoryEntryName(directory)
						If (name$<>".") And (name$<>"..") ;. and .. are parent and current folder, we must ignore them to avoid a potential deadlock loop
							AddElement(folders())
							folders()=folder$+name$+delim$ ;add the folder to the list
						EndIf
					EndIf
				Wend
				FinishDirectory(directory)
			EndIf
		Wend
	EndIf
	ProcedureReturn size
EndProcedure


path.s = PathRequester("Choose a folder...", "") ;choose a folder ...

Debug GetFolderSize(path)
While this example just gets the size of files / directory size or folder size and the size of sub-folders or sub-directories you can easily edit this to suit other needs.

EDIT: Added the delim suggestion by michel51 in http://www.purebasic.fr/english/viewtop ... 11#p405611 also added some extra checks on initial folder.

Re: GetFolderSize()

Posted: Fri Feb 22, 2013 3:20 am
by IdeasVacuum
Nice fast code Rescator, thanks for sharing it. 8)

Re: GetFolderSize()

Posted: Fri Feb 22, 2013 5:03 am
by rsts
Very nice.

Thanks for sharing.

cheers

Re: GetFolderSize()

Posted: Fri Feb 22, 2013 8:44 am
by MachineCode
Hmm, totally fails here. Says "c:\windows\system32\" is 2,593,410,518, but system properties for the folder says 3,621,412,292 bytes.

Re: GetFolderSize()

Posted: Fri Feb 22, 2013 10:25 am
by davido
I get similar inconsistencies with windows folders, maybe its a problem with some of the files theirin?

It also gets my C: Drive wrong 41,811,251,024 whereas 'properties' gives 34,568,093,696 as would be expected from above.

The good news is: It works ok for all the other ordinary folders I have tried. Thank you for sharing.

Re: GetFolderSize()

Posted: Fri Feb 22, 2013 12:08 pm
by michel51
Good job, rescator. Thanks for sharing.

I've changed your code a little bit, so it runs on Mac too. LINUX not tested, but it should run in the same way.

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  #Delim$ = "\"
CompilerElse   ; Mac Os  und Linux
  #Delim$ = "/"
CompilerEndIf

Procedure.q GetFolderSize(folder$)
   Protected size.q,NewList folders.s(),directory.i,name$
   If Right(folder$,1)<>#Delim$
      folder$=folder$+#Delim$ ;make sure the folder name ends with \ (WIndows)  or / (Linux/Mac Os)
   EndIf
   AddElement(folders())
   folders()=folder$ ;add the main folder to the list
   While ListSize(folders())
      folder$=folders()
      DeleteElement(folders(),1) ;remove the folder from the list
      directory=ExamineDirectory(#PB_Any,folder$,"")
      If directory
         While   NextDirectoryEntry(directory)
            If DirectoryEntryType(directory)=#PB_DirectoryEntry_File
               size+DirectoryEntrySize(directory) ;add the entry size to total size so far
            Else
               name$=DirectoryEntryName(directory)
               If (name$<>".") And (name$<>"..") ;. and .. are parent and current folder, we must ignore them to avoid a potential deadlock loop
                  AddElement(folders())
                  folders()=folder$+name$+#Delim$ ;add the folder to the list
               EndIf
            EndIf
         Wend
         FinishDirectory(directory)
      EndIf
   Wend
   ProcedureReturn size
EndProcedure


path.s = PathRequester("Choose a folder...", "")	, choose a folder ...

Debug GetFolderSize(path)
Hope the code is ok :-)

Re: GetFolderSize()

Posted: Fri Feb 22, 2013 3:31 pm
by SFSxOI
Thanks Rescator

Returns the size, not the size on disk (the drive). Nice. :)

Re: GetFolderSize()

Posted: Fri Feb 22, 2013 8:57 pm
by Rescator
Updated the first post. Thanks michel51. And if you are wondering why I did the delim a little differently, it is to make sure the procedure is fully self contained.

And to answer the space vs space "issue".

Windows/The OS do restrict access to certain files. Some folders on C are for the OS or machine admin only.

As to the disk size used, that is not possible using PureBasic commands. You need to use the OS API for that as a file may physically be split across multiple storage devices all with different block sizes, a part of a file or a select few files may even be stored in a cloud service.