GetDiskFreeSpaceEx函数的一点处理

GetDiskFreeSpaceEx()函数可以得到驱动器的簇信息,剩余空间以及总大小。

函数原型:

BOOL GetDiskFreeSpaceEx(
  LPCTSTR lpDirectoryName,            // directory name
  PULARGE_INTEGER lpFreeBytesAvailable,    // bytes available to caller
  PULARGE_INTEGER lpTotalNumberOfBytes,    // bytes on disk
  PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
);

函数的用法就不多讲了,讲一下PULARGE_INTEGER。我们这个函数得到的信息是磁盘的总大小、当前用户可操作大小、剩余磁盘空间,单位是字节。但是在我的电脑上int 以及 long int都是4个字节,也就是最大(无符号)能存是数2<sup>32</sup>字节,等于4G左右,显然已经不够了,现在随意一个分区就是几百G。所以这个函数用了一个特别的方法,即用一个联合,里面保存着一个结构体,而结构体里面有两个32位的整数,分别表示该数的上半部分和下半部分。于是就可以表示出一个64位的整数了。

在winnt.h中可以看到以下定义(省略了一部分):

typedef union _ULARGE_INTEGER {
  struct {
    DWORD LowPart;
    DWORD HighPart;
  } u;
  ULONGLONG QuadPart;
} ULARGE_INTEGER, *PULARGE_INTEGER;

看到了吗,所以PULARGE_INTEGER其实指向的是这个联合,这个联合中的结构体中的LowPart表示低32位,HighPart表示高32位。

假如我们调用这个函数

GetDiskFreeSpaceEx(TEXT("D:"),&FreeBytesAvailable,&TotalNumberOfBytes,&TotalNumberOfFreeBytes);

得到了TotalNumberOfBytes这个联合。里面便是D盘总大小,单位是字节。我们可以直接把他输出

printf("%I64d",TotalNumberOfBytes);

不过输出得到的是一大串数字(因为是以字节为单位),如果我们想以MB或GB为单位怎么办呢?直接拿TotalNumberOfBytes/1024/1024,发现编译会报错。你拿一个联合去和一个整数做除法运算,肯定报错。

所以我在这里给大家提供一个方法:

int iTotal = (TotalNumberOfBytes.u.HighPart << 12) + (TotalNumberOfBytes.u.LowPart >> 20);

什么意思?将高32位向左移12位,将低32位向右移20位,再相加,目的是什么?先看将LowPart向右移20位,剩下的其实就是LowPart的左12位。因为我们要得到以MB为单位,而1MB是2^20字节,所以只保留LowPart的左12位。而HighPart的所有位都应该保留,所以要放在第13位以后,故HighPart左移12位,最后相加。

得到的iTotal再想转换成GB就除以1024.0就可以了。

赞赏

喜欢这篇文章,扫码和我成为赞友!

评论

captcha