Page 1 of 1

Get the size of a directory in bytes

Posted: Fri Jul 25, 2003 9:26 pm
by Kale
Code updated for 5.20+

Just so its not lost in another post i'll echo it here :)

Code: Select all

;Return the size of a directory in bytes
Procedure.q DirectorySize(DirectoryID, DirectoryName.s)
  If ExamineDirectory(DirectoryID, DirectoryName, "*.*")
    While NextDirectoryEntry(DirectoryID)
      
      Name.s = DirectoryEntryName(DirectoryID)
      
      If DirectoryEntryType(DirectoryID) = #PB_DirectoryEntry_File
        TotalFileSize.q + DirectoryEntrySize(DirectoryID)
        
      ElseIf DirectoryEntryType(DirectoryID) = #PB_DirectoryEntry_Directory
        If Name <> "." And Name <> ".."
          TotalFileSize + DirectorySize(DirectoryID + 1, DirectoryName + Name + "\")
        EndIf
      EndIf
      
    Wend
  EndIf
  ProcedureReturn TotalFileSize
EndProcedure

Debug DirectorySize(1, "C:\Windows\")

Problem...

Posted: Sat Jul 26, 2003 3:35 pm
by Hi-Toro
There's an important problem with this, one which I ran into myself when I tried a similar thing: if you run it on a really large folder, it overflows the 'long' variable used to store the size, resulting in a negative number. I think this requires the use of 64-bit integers. There's a library on www.reelmediaproductions.com/pb/ that I meant to try and fix my version with, but haven't got around to doing it yet!

Posted: Sun Jul 27, 2003 1:53 am
by freak
Here is an example that calculates with 64bit math:

Code: Select all

Structure d
  lowLONG.l
  hiLONG.l
EndStructure

Procedure.s StrD(*value.d)
  Protected buffer1.s, buffer2.s, buffer3.s, pos1.l, pos2.l, pos3.l, calc1.l, calc2.l
  buffer3 = StrU(*value\lowLONG,#LONG)
  For pos1 = Len(StrU(*value\hiLONG,#LONG)) To 1 Step -1
    For pos2 = Len(StrU(-1,#LONG)) To 1 Step -1
      calc1 = Val(Mid(StrU(*value\hiLONG,#LONG),pos1,1)) * Val(Mid(StrU(-1,#LONG),pos2,1))
      calc2 = (Len(StrU(*value\hiLONG,#LONG))-pos1)+(Len(StrU(-1,#LONG))-pos2)
      buffer1 = Str(calc1) + Left("00000000000000000000",calc2)
      buffer2 = buffer3
      buffer3 = ""
      calc1 = 0
      If Len(buffer1) > Len(buffer2)
        buffer2 = Right("00000000000000000000"+buffer2,Len(buffer1))
      Else
        buffer1 = Right("00000000000000000000"+buffer1,Len(buffer2))
      EndIf
      For pos3 = Len(buffer1) To 1 Step -1
        calc1 + Val(Mid(buffer1,pos3,1)) + Val(Mid(buffer2,pos3,1))
        buffer3 = Right(Str(calc1),1)+buffer3
        calc1/10
      Next pos3
      If calc1 > 0: buffer3 = Str(calc1)+buffer3: EndIf
    Next pos2
  Next pos1
  While Left(buffer3,1)="0"
    buffer3 = Right(buffer3, Len(buffer3)-1)
  Wend
  ProcedureReturn buffer3
EndProcedure

Procedure AddD(*dest, *source1, *source2)
  !mov eax, [esp+4]
  !mov ebx, [eax]
  !mov edx, [eax+4]
  !mov eax, [esp+8]
  !add ebx, [eax]
  !adc edx, [eax+4]
  !mov eax, [esp+0]
  !mov [eax], ebx
  !mov [eax+4], edx  
EndProcedure

Procedure DirectorySize(DirectoryID.l, DirectoryName.s, *size.d) 
  If ExamineDirectory(DirectoryID, DirectoryName, "*.*") 
    Repeat 
      Entry.l = NextDirectoryEntry() 
      Name.s = DirectoryEntryName() 
      If Entry = 1 
        newsize.d
        hFile.l = ReadFile(0, DirectoryName + Name)
        If hFile
          newsize\lowLONG = GetFileSize_(hFile, @newsize\hiLONG)
          AddD(*size, *size, newsize)
          CloseFile(0)
        EndIf
      ElseIf Entry = 2 
        If Name <> "." And Name <> ".." 
          DirectorySize(DirectoryID + 1, DirectoryName + Name + "\", *size) 
          UseDirectory(DirectoryID) 
        EndIf 
      EndIf 
    Until Entry = 0 
  EndIf 
EndProcedure 

DirectorySize(0, "C:\WINNT\", size.d)
Debug StrD(size)
End
There must be a better way to do the StrD() procedure, but i haven't found
one yet.

[edit] MMX no longer needed [/edit]

Timo

Posted: Fri Aug 01, 2003 7:35 pm
by Kale
Excellent code Timo (as always) :D

Posted: Fri Aug 01, 2003 8:12 pm
by Pupil
> There must be a better way to do the StrD() procedure, but i haven't found one yet.

Try out this, it might seem a bit long but if you peel off some of the fancy stuff the resulting procedure should be quite slim :)
viewtopic.php?t=5223

All good stuff...

Posted: Fri Aug 01, 2003 9:22 pm
by Hi-Toro
... but can anyone do it without assembly? Just curious -- it would be handy for use on non-x86 platforms... :)