windows下編程獲取磁盤(分區)使用情況
linux下可以使用命令df -h來獲取各個(已加載)分區的使用情況。Windows下也有很多好的工具來獲取,但是我沒有發現windows下的df命令。
在linux下使用df -h命令的輸出如下
o@Neo-kylin:~/snmp$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 197G 14G 174G 8% /
tmpfs 922M 76K 922M 1% /dev/shm
/dev/sda5 61G 7.8G 50G 14% /media/sda5
/dev/sda6 134G 29G 99G 23% /media/sda6
在windows下獲取這些信息可以通過幾個API函數來操作。
GetLogicalDriveStrings函數
Windows的API函數名稱一般都很長,雖然不好記,但是描述的意思比較清晰。這個函數就是用於獲取邏輯驅動器字符串。
GetLogicalDriveStrings實際上是一個宏,在沒有定義UNICODE宏的條件下,它被替換為GetLogicalDriveStringA函數,在定義了UNICODE宏的條件下,它被替換為GetLogicalDriveStringsW函數。
這兩個函數的聲明如下
DWORD GetLogicalDriveStringsA( DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return + 1) LPSTR lpBuffer );
DWORD
GetLogicalDriveStringsW(
DWORD nBufferLength,
_Out_writes_to_opt_(nBufferLength, return + 1) LPWSTR lpBuffer
);
這個的參數看起來很復雜,其實並沒有。函數需要提供一個內存緩沖區lpBuffer來供它保存獲取的邏輯驅動器的分區號(C:\ ,D:\等)信息。
如果參數nBufferLength填寫0,那么將緩沖區將不使用,函數返回保存所有數據所需要的字節數。這通常用戶獲取需要的緩沖區大小。
應該總是比較返回值與參數nBufferLength的大小。
如果函數成功,返回值是復制到緩沖區的字符串的長度, 不包括結束符null。注意,ansi-ascii的null字符用一個字節,但 Unicode(UTF-16)null字符用兩個字節。
如果緩沖區不夠大,返回值是大於nbufferlength。它要求具有能夠保持驅動字符串大小的緩沖區。
如果函數失敗,返回值是零。為了獲得更多的錯誤信息,可以使用GetLastError函數。
這里不講UNICODE與多字節字符集的區別。指導一點就好,使用多字節字符集的時候,當作普通的C風格字符串來使用即可。
使用示例
獲取需要的緩沖區長度示例
#include <stdio.h>
#include <Windows.h>
int main()
{
DWORD dw = GetLogicalDriveStrings(0,NULL);
printf("dw = %lu\n",dw); return 0;
}
編譯后運行輸出

獲取所有驅動器號示例
#include <stdio.h>
#include <Windows.h>
int main()
{
DWORD dwSize = MAX_PATH;
char szLogicalDrives[MAX_PATH] = {0};
//獲取邏輯驅動器號字符串
DWORD dwResult = GetLogicalDriveStrings(dwSize,szLogicalDrives);
//處理獲取到的結果
if (dwResult > 0 && dwResult <= MAX_PATH) {
char* szSingleDrive = szLogicalDrives; //從緩沖區起始地址開始
while(*szSingleDrive) {
printf("Drive: %s\n", szSingleDrive); //輸出單個驅動器的驅動器號
// 獲取下一個驅動器號起始地址
szSingleDrive += strlen(szSingleDrive) + 1;
}
}
return 0;
}
編譯后運行輸出

GetDriveType函數
GetDriveType函數用於判斷一個磁盤驅動器的類型。
函數聲明如下
UINT WINAPI GetDriveType(
_In_opt_ LPCTSTR lpRootPathName
);
參數lpRootPathName包含了根目錄路徑的字符串指針。
如驅動器不能識別,則返回零。如指定的目錄不存在,則返回1。如執行成功,則用下述任何一個常數指定驅動器類型
| 常數 | 含義 |
|---|---|
| DRIVE_UNKNOWN | 未知的磁盤類型 |
| DRIVE_NO_ROOT_DIR | 說明lpRootPathName是無效的 |
| DRIVE_REMOVABLE | 可移動磁盤 |
| DRIVE_FIXED | 固定磁盤 |
| DRIVE_REMOTE | 網絡磁盤 |
| DRIVE_CDROM | 光驅 |
| DRIVE_RAMDISK | RAM映射磁盤 |
使用示例
獲取所有驅動器號及其所屬磁盤類型示例
輸出邏輯驅動器類型函數
#include <stdio.h>
#include <Windows.h>
void putDrivesType(const char* lpRootPathName)
{
UINT uDriverType = GetDriveType(lpRootPathName);
switch(uDriverType) {
case DRIVE_UNKNOWN :puts("未知的磁盤類型"); break;
case DRIVE_NO_ROOT_DIR: puts("路徑無效"); break;
case DRIVE_REMOVABLE: puts("可移動磁盤"); break;
case DRIVE_FIXED: puts("固定磁盤"); break;
case DRIVE_REMOTE: puts("網絡磁盤"); break;
case DRIVE_CDROM: puts("光驅"); break;
case DRIVE_RAMDISK: puts("內存映射盤"); break;
default:
break;
}
}
調用
int main()
{
DWORD dwSize = MAX_PATH;
char szLogicalDrives[MAX_PATH] = {0};
//獲取邏輯驅動器號字符串
DWORD dwResult = GetLogicalDriveStrings(dwSize,szLogicalDrives);
//處理獲取到的結果
if (dwResult > 0 && dwResult <= MAX_PATH) {
char* szSingleDrive = szLogicalDrives; //從緩沖區起始地址開始
while(*szSingleDrive) {
printf("Drive: %s\n", szSingleDrive); //輸出單個驅動器的驅動器號
putDrivesType(szSingleDrive); //輸出邏輯驅動器類型
// 獲取下一個驅動器號起始地址
szSingleDrive += strlen(szSingleDrive) + 1;
}
}
return 0;
}
編譯后運行輸出

GetDiskFreeSpaceEx 函數
GetDiskFreeSpaceEx函數用戶獲取邏輯驅動器的容量信息。還有一個和它長得很像的函數GetDiskFreeSpace,但這個函數已經過時了,不推薦使用。
函數聲明如下
BOOL WINAPI GetDiskFreeSpaceEx(
_In_ LPCTSTR lpRootPathName,
_Out_ LPDWORD lpSectorsPerCluster,
_Out_ LPDWORD lpBytesPerSector,
_Out_ LPDWORD lpNumberOfFreeClusters,
_Out_ LPDWORD lpTotalNumberOfClusters
);
這個函數的參數要仔細的說明一下。
| 參數 | 含義 |
|---|---|
| lpDirectoryName | 邏輯驅動器的名稱(C/D/E等這些) |
| lpFreeBytesAvailableToCaller | 用戶(當前線程)可用的磁盤空間字節數 |
| lpTotalNumberOfBytes | 邏輯磁盤總的空間字節數 |
| lpTotalNumberOfFreeBytes | 邏輯磁盤空閑的空間字節數 |
上面三個字節數的單位都是字節,數據類型都是64位無符號整型。
GetDiskFreeSpaceEx函數執行成功返回非0值,失敗返回0。可以通過GetLastError函數獲取失敗信息。
使用示例
獲取磁盤容量信息示例
下面的函數用來輸出磁盤的容量信息。
void putDrivesFreeSpace(const char* lpRootPathName)
{
unsigned long long available,total,free;
if(GetDiskFreeSpaceEx(lpRootPathName,(ULARGE_INTEGER*)&available,(ULARGE_INTEGER*)&total,(ULARGE_INTEGER*)&free)){
printf("Drives %s | total = %lld MB,available = %lld MB,free = %lld MB\n",
lpRootPathName,total>>20,available>>20,free>>20);
}else{
puts("獲取容量信息失敗");
}
}
調用如下
int main()
{
DWORD dwSize = MAX_PATH;
char szLogicalDrives[MAX_PATH] = {0};
//獲取邏輯驅動器號字符串
DWORD dwResult = GetLogicalDriveStrings(dwSize,szLogicalDrives);
//處理獲取到的結果
if (dwResult > 0 && dwResult <= MAX_PATH) {
char* szSingleDrive = szLogicalDrives; //從緩沖區起始地址開始
while(*szSingleDrive) {
printf("Drive: %s\n", szSingleDrive); //輸出單個驅動器的驅動器號
putDrivesType(szSingleDrive); //輸出邏輯驅動器類型
putDrivesFreeSpace(szSingleDrive);
// 獲取下一個驅動器號起始地址
szSingleDrive += strlen(szSingleDrive) + 1;
}
}
return 0;
}
編譯后運行輸出

