How to get current Disk Space Free?

Blitz3D Forums/Blitz3D Programming/How to get current Disk Space Free?

Danny(Posted 2012) [#1]
I want to check if there's enough disk space on a given volume before saving an amount of data. But haven't got a clue to do this :)

I found a BMax reference here, but don't know how/if this can be done in B3D. http://www.blitzbasic.com/Community/posts.php?topic=64341

Is uses kernal32's:
GetDiskFreeSpaceEx:Long( WindowText$z, FreeBytesToCaller:Long Ptr, TotalBytes:Long Ptr, TotalFree:Long Ptr ) = "GetDiskFreeSpaceExA@16"



Cheers,
Danny.


Yasha(Posted 2012) [#2]
The proper documentation for the function is here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364937%28v=vs.85%29.aspx

There's also this related function (which is probably not what you want, but let's mention it anyway): http://msdn.microsoft.com/en-us/library/windows/desktop/aa364935%28v=vs.85%29.aspx

Note that the first of these is not declared in the Kernel32 code archives userlib, and the second one is declared incorrectly (awesome going, guys!). Um. The correct userlib declaration for the function GetDiskFreeSpaceEx is as follows:

.lib "Kernel32.dll"

API_GetDiskFreeSpaceEx%(lpDirectoryName$, lpFreeBytesAvailable*, lpTotalNumberOfBytes*, lpTotalNumberOfFreeBytes*) : "GetDiskFreeSpaceExA"


The first parameter should be the path to check, and the other three should be the handles to banks (or pointers to objects) of at least eight bytes in length. These will receive the space data in three separate long-integers (note that the long integer data type is not natively supported by B3D - you'll have to find a way to decode this).

The function's main return value is a success/fail indicator.


A (possibly accurate) example of how to wrap this in a simpler-to-use function might look something like this:



Note however:

The value returned by this example is unusable, because the number of bytes of free space on a modern hard disk will rarely fit into a Blitz-style short integer (which overflows at 4.2 billion) - that's why this function returns the data into LongInts. You'll need some way to use the massive values it returns without putting them into Blitz ints (perhaps you could shift it right a few points and use the free space rounded to the nearest megabyte?).

Also, I make no guarantee that this example is the right way to go about this anyway, 'cause I'm an idiot and I've never used this before.


Danny(Posted 2012) [#3]
Excellent! Thanks for your time and explanation Yasha. Yes I noticed those long integers and they gave me the shivers :)

By the way, I didn't see that trick before using types in stead of banks to get values back like that, nice one!

In my situation I only need to know if there's, for example 2 Or 3 megabytes free before writing a file to disk. So this solution will surely suffice!

Thanks!

Danny


Yasha(Posted 2012) [#4]
I only need to know if there's, for example 2 Or 3 megabytes free


In that case you probably don't need to bother with trying to do maths on the Long value. You can instead do simpler checks on the int components:

-- if \b is nonzero, there are more than 4.2 GBs free. Yay.
-- if \b is zero but \a is negative, there are more than 2.1 GBs free. Yay.
-- if neither of those, the value in \a can be checked as a regular Blitz int.

I know it's not great practice to assume things about byte order and word sizes, but Blitz3D ain't likely to change any time soon (besides, too much existing code depends on things staying as they are).


Adam Novagen(Posted 2012) [#5]
I would suggest coding an extremely simple DLL which takes the long integer directly from API_GetFreeDiskSpaceEx%(), splits it into two integers using something like the following Blitz code:

Global LongHigh,LongLow

LongHigh = (FreeSpace("C:\") And %1111111111111111111111111111111100000000000000000000000000000000) Shr 32
LongLow = FreeSpace("C:\") And %0000000000000000000000000000000011111111111111111111111111111111

then just returns the two integers for use. Having never attempted a Blitz3D DLL in my life, though, I have no idea how easy this would be to put into practice. Might be a worthwhile experiment for me!


Danny(Posted 2012) [#6]
If I had the skills, I would make a dll for it, but unfortunately I don't.

I've added the function to the code archives.

http://www.blitzbasic.com/codearcs/codearcs.php?code=2934

Thanks for helping out!

Danny.