[bb] Check Free Disk Space by Danny [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:42

Previous topic - Next topic

BlitzBot

Title : Check Free Disk Space
Author : Danny
Posted : 1+ years ago

Description : The routine below is based on Yasha's example in the forum.
See here: <a href="../Community/postsea57.html?topic=97357" target="_blank">http://www.blitzbasic.com/Community/posts.php?topic=97357</a>

It may help you when you want to check that there's enough space left on a given device before saving an amount of data to it. Since B3D doesn't support long integers, it can only check up to a specific max of 2.1 Gb being free - or not.
Also note that you should supply the path you intend to write data to, not just the drive, since some windows configurations might use user-based disk quotas. See here for more info on that: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/windows/desktop/aa364937%28v=vs.85%29.aspx</a>

Enjoy.

Danny


Code :
Code (blitzbasic) Select
; Add to Kernal32.decls:
;
; .lib "Kernel32.dll"
; API_GetDiskFreeSpaceEx%(lpDirectoryName$, lpFreeBytesAvailable*, lpTotalNumberOfBytes*, lpTotalNumberOfFreeBytes*) : "GetDiskFreeSpaceExA"


Type LongInt
Field a%, b%
End Type

Function HasFreeSpace%(path$, minFreeBytes%)

;# Returns TRUE (1), FALSE(0) or -1 when path not found/accessible/mounted
;
;# Max bytes that can be tested is 2,147,483,647 bytes (=2.1Gb = 2048 Mb)
;# Thus always returns TRUE if more than 2.1Gb is free!

If minFreeBytes < 0 Then minFreeBytes = ((2048 *1024) *1024) -1

GFS_out_FABytes.LongInt = New LongInt
GFS_out_TotBytes.LongInt = New LongInt
GFS_out_TFBytes.LongInt = New LongInt

Local ret% = False

If API_GetDiskFreeSpaceEx(path, GFS_out_FABytes, GFS_out_TotBytes, GFS_out_TFBytes)

If GFS_out_FABytes <> 0
; when B <> 0 then MORE than 4.2Gb free
ret = True
ElseIf (GFS_out_FABytes = 0) And (GFS_out_FABytesa < 0)
; when B = 0, A < 0, MORE than 2.1Gb free
ret = True
ElseIf GFS_out_FABytesa > minFreeBytes Then
; A contains remaining bytes free
ret = True
Else
; NOT ENOUGH SPACE FREE!
ret = False
EndIf

Else
; Path not found, drive doesn't exist or media not mounted
ret = -1

EndIf

; purge
Delete GFS_out_FABytes
Delete GFS_out_TotBytes
Delete GFS_out_TFBytes
; return
Return ret

End Function


; EXAMPLE USE

Local drive$ = "C:"

Local megabyte% = 100
Local bytes% = ((megabyte *1024) *1024)

Select HasFreeSpace(drive, bytes)
Case True
Print " "+drive+" has more than "+megabyte+" Mb free ("+bytes+" bytes)"
Case False
Print " "+drive+" DOES NOT have "+megabyte+" Mb free ("+bytes+" bytes) !"
Case -1
Print " "+drive+" not accessible, found or mounted!"
End Select

Print "" : Print " <any key>"
WaitKey
End


Comments :


Yasha(Posted 1+ years ago)

 This version has a (kinda) memory leak - you're creating the three LongInt objects anew each time but not freeing them afterwards (this is why in the original example I cached them in a global). If you use this function more than once, it will start to waste space.You don't have to store them between calls, if you want to keep the surrounding code tidier, but in that case you do need to have a corresponding Delete section at the bottom.(I say "kinda" because objects in B3D created with New are never truly unreachable - you can quickly kill 'em all with "Delete Each LongInt". However, unless you do something like this somewhere in your program it's effectively the same as a leak.)


Danny(Posted 1+ years ago)

 Ay, yes I thought about then when removing the Globals, but forgot to put the Deletes in. The code above is updated so should be safe now.Thanks for pointing that out ;)