Как определить размер свободного места на диске?
Для определения свободного места на диске в Win32 используются функции GetDiskFreeSpaceEx или GetDiskFreeSpace. В принципе, функция GetDiskFreeSpaceEx возвращает всю необходимую информацию, включая свободное место доступное пользователю, ассоциированному с вызывающим потоком. Но, как это обычно бывает с удобными и полезными функциями, она отсутствует в ранних версиях Windows и появилась только в Windows 95 OSR2.
Если Вы разрабатываете приложения, способные работать со всеми версиями Windows, то этот факт исключает возможность применения данной функции. С другой стороны, отказываться от преимуществ, которые даёт GetDiskFreeSpaceEx неразумно. Раз нам нельзя воспользоваться прямым вызовом функции, значит следует воспользоваться другим способом, а именно через вызов GetProcAddress. Функция, приведённая ниже, производит проверку наличия функции GetDiskFreeSpaceEx в системе и если не находит её, то выполняет вызов GetDiskFreeSpace.
#include <stdlib.h> #include <tchar.h> #ifdef UNICODE #define nmGetDiskFreeSpaceEx "GetDiskFreeSpaceExW" #else #define nmGetDiskFreeSpaceEx "GetDiskFreeSpaceExA" #endif BOOL GetPathFreeSpace (LPCTSTR szPath,LARGE_INTEGER& liSize) { liSize.LowPart = 0; liSize.HighPart = 0; HMODULE hm = ::GetModuleHandle(TEXT("KERNEL32.DLL")); if (hm != 0) { typedef BOOL (WINAPI *GDFSEx)(LPCSTR,PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); GDFSEx func = (GDFSEx)GetProcAddress(hm,nmGetDiskFreeSpaceEx); if (func) { ULARGE_INTEGER liFreeAvailable, liTotal; if (func(szPath,&liFreeAvailable, &liTotal, NULL)) { liSize.QuadPart = liFreeAvailable.QuadPart; return TRUE; } // return FALSE; } } TCHAR szDrive[_MAX_DRIVE+10]; if (szPath != NULL) { _tsplitpath(szPath,szDrive,0,0,0); if (szDrive[0] == 0) { TCHAR szPath[MAX_PATH]; ::GetCurrentDirectory(MAX_PATH,szPath); _tsplitpath(szPath,szDrive,0,0,0); } _tcscat(szDrive,TEXT("\\")); szPath = szDrive; } DWORD dwSecPerClus, dwBytesPerSec, dwFreeClus, dwTotalClus; if (::GetDiskFreeSpace( szPath, &dwSecPerClus,&dwBytesPerSec,&dwFreeClus,&dwTotalClus)) { liSize.QuadPart = __int64(dwFreeClus) * dwSecPerClus * dwBytesPerSec; return TRUE; } return FALSE; } |
Эта функция принимает в качестве параметра путь к каталогу, а не просто диск. Дело в том, что GetDiskFreeSpaceEx позволяет получать информацию не просто о свободном пространстве, а о доступном пространстве на диске для текущего пользователя в заданной директории. Но, если Вы ошибётесь и неправильно зададите путь, то GetDiskFreeSpaceEx вернёт ошибку и будет произведена попытка получить необходимую информацию через GetDiskFreeSpace. Если такая возможность Вам не нужна, то откомментируйте строчку:
|
Если в качестве первого параметра задать NULL, то будет выполнено определение свободного места для текущего каталога или диска.
Функция возвращает значение в структуре LARGE_INTEGER, которая состоит из двух 32-х битных полей LowPart и HighPart. При этом через поле QuadPart можно получить доступ к 64-х разрядному значению типа __int64.