Code archives/File Utilities/Check Free Disk Space

This code has been declared by its author to be Public Domain code.

Download source code

Check Free Disk Space by Danny2012
The routine below is based on Yasha's example in the forum.
See here: http://www.blitzbasic.com/Community/posts.php?topic=97357

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: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364937%28v=vs.85%29.aspx

Enjoy.

Danny
; 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\b <> 0 
			; when B <> 0 then MORE than 4.2Gb free
			ret = True
		ElseIf (GFS_out_FABytes\b = 0) And (GFS_out_FABytes\a < 0)
			; when B = 0, A < 0, MORE than 2.1Gb free
			ret = True
		ElseIf GFS_out_FABytes\a > 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

Yasha2012
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.)


Danny2012
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 ;)


Code Archives Forum