GetFolderSize()

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

GetFolderSize()

Post 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.
Last edited by Rescator on Fri Feb 22, 2013 8:52 pm, edited 2 times in total.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: GetFolderSize()

Post by IdeasVacuum »

Nice fast code Rescator, thanks for sharing it. 8)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: GetFolderSize()

Post by rsts »

Very nice.

Thanks for sharing.

cheers
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: GetFolderSize()

Post 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.
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: GetFolderSize()

Post 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.
DE AA EB
User avatar
michel51
Enthusiast
Enthusiast
Posts: 290
Joined: Mon Nov 21, 2005 10:21 pm
Location: Germany

Re: GetFolderSize()

Post 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 :-)
michel51

Mac OS X Snow Leopard (10.6.8 ) Intel
PureBasic V 5.21(x64), V 5.22beta
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: GetFolderSize()

Post by SFSxOI »

Thanks Rescator

Returns the size, not the size on disk (the drive). Nice. :)
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Re: GetFolderSize()

Post 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.
Post Reply