views:

887

answers:

4

I need to know how big a given in-memory buffer will be as an on-disk (usb stick) file before I write it. I know that unless the size falls on the block size boundary, its likely to get rounded up, e.g. a 1 byte file takes up 4096 bytes on-disk. I'm currently doing this using GetDiskFreeSpace() to work out the disk block size, then using this to calculate the on-disk size like this:

GetDiskFreeSpace(szDrive, &dwSectorsPerCluster, 
                 &dwBytesPerSector, NULL, NULL);

dwBlockSize = dwSectorsPerCuster * dwBytesPerSector;

if (dwInMemorySize % dwBlockSize != 0)
{
    dwSizeOnDisk = ((dwInMemorySize / dwBlockSize) * dwBlockSize) + dwBlockSize;
}
else
{
    dwSizeOnDisk = dwInMemorySize;
}

Which seems to work fine, BUT GetDiskFreeSpace() only works on disks up to 2GB according to MSDN. GetDiskFreeSpaceEx() doesn't return the same information, so my question is, how else can I calculate this information for drives >2GB? Is there an API call I've missed? Can I assume some hard values depending on the overall disk size?

+1  A: 

You should be able to obtain this information using the DeviceIoControl function and
DISK_GEOMETRY_EX. It will return a structure that contains the information you are looking for I think

http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms809010.aspx

RA
+1  A: 

MSDN only states that the GetDiskFreeSpace() function cannot report volume sizes greater than 2GB. It works fine for retrieving sectors per cluster and bytes per sector, I've used it myself for very similar-looking code ;-)

But if you want disk capacity too, you'll need an additional call to GetDiskFreeSpaceEx().

snowcrash09
That'll teach me to read the documentation more closely! I've just tried the code on my hard disk and it seems to work just fine. Thanks.
porkchop
+1  A: 

The size of a file on disk is a fuzzy concept. In NTFS, a file consists of a set of data elements. You're primarilty thinking of the "unnamed data stream". That's an attribute of a file that, if small, can be packed with the other attributes in the directory entry. Apparently, you can store a data stream of up to 700-800 bytes in the directory entry itself. Hence, your hypothetical 1 byte file would be as big as a 0 byte of 700 byte file.

Another influence is file compression. This will make the on-disk size potentially smaller than the in-memory size.

MSalters
A: 

In actionscript!

var size:Number = 19912;
var sizeOnDisk:Number = size;
var reminder:Number = size % (1024 * 4);
if(reminder>0){
    sizeOnDisk = size + ((1024 * 4)- reminder)
}
trace(size)
trace(sizeOnDisk)
karthick