Шрифт:
Теперь напишем несложные функции, позволяющие определить полный размер и размер свободного пространства на диске (листинг 4.3).
Листинг 4.3.
Определение полного размера и размера свободного пространства диска
//Функция возвращает полный размер диска в байтах
function GetDriveSize(root: String): Int64;
var
freeToCaller, totalBytes, freeBytes: Int64;
begin
if GetDiskFreeSpaceEx(PAnsiChar(root), freeToCaller,
totalBytes, PLargeInteger(Addr(freeBytes))) <> False
then
GetDriveSize := totalBytes
else
GetDriveSize := -1;
end;
//Функция возвращает размер свободного места на диске (в байтах)
function GetDriveFreeSpace(root: String): Int64;
var
freeToCaller, totalBytes, freeBytes:Int64;
begin
if GetDiskFreeSpaceEx(PAnsiChar(root), freeToCaller,
totalBytes, PLargeInteger(Addr(freeBytes))) <> False
then
GetDriveFreeSpace := freeBytes
else
GetDriveFreeSpace := –1;
end;
В обеих функциях листинга 4.3 для достижения двух разных целей используется API-функция GetDiskFreeSpaceEx:
function GetDiskFreeSpaceEx(lpDirectoryName: PChar;
var lpFreeBytesAvailableToCaller,
lpTotalNumberOfBytes;
lpTotalNumberOfFreeBytes: PLargeInteger): BOOL;
Функция принимает путь (любой) файла или папки на интересующем диске и заполняет три параметра:
• lpFreeBytesAvailableToCaller – размер свободного пространства, доступного пользователю, под чьими правами работает поток, вызывающий функцию (в байтах);
• lpTotalNumberOf Bytes – полный размер диска (в байтах);
• lpTotalNumberOf FreeBytes – размер свободного пространства на диске (в байтах).
Все перечисленные значения являются 64-битными, чтобы можно было оперировать размерами дисков более 4 Гбайт. Если вызов функции GetDiskFreeSpaceEx оказывается неудачным, то возвращается значение False. В этом случае функции листинга 4.3 возвращают -1, сигнализируя об ошибке.
Теперь самое интересное – определение детальной информации о файловой системе на дисках. Много интересного о файловой системе на каждом диске можно узнать при помощи API-функции GetVolumelnformation. Она имеет следующий вид:
function GetVolumeInformation(lpRootPathName: PChar;
lpVolumeNameBuffer: PChar; nVolumeNameSize: DWORD;
lpVolumeSerialNumber: PDWORD; var lpMaximumComponentLength,
lpFileSystemFlags: DWORD; lpFileSystemNameBuffer: PChar;
nFileSystemNameSize: DWORD): BOOL;
Объявление функции выглядит довольно громоздким за счет большого количества параметров. Однако использовать функцию GetVolumelnformation очень просто. Чтобы не вдаваться в долгое описание ее параметров, рассмотрим ее использование на примере (листинг 4.4).
Листинг 4.4.
Определение информации о диске
//Функция определяет информацию о диске
//Возвращает False, если возникла ошибка
function GetDriveInformation(root: String;
var info: DriveInfo):Boolean;
var
bufDriveName, bufFSNAme: String;
SN: DWORD;
maxFileName, fsOptions: Cardinal;
begin
SetLength(bufDriveName, 101);
SetLength(bufFSName, 101);
//Определение информации о диске
if GetVolumeInformation(PAnsiChar(root),
PAnsiChar(bufDriveName), 100,
Addr(SN), maxFileName, fsOptions,
PAnsiChar(bufFSName), 100) <> False
then
begin
//Заполняем структуру информацией о диске
with info do
begin
DriveLabel := bufDriveName;
FileSystemName := bufFSName;
SerialNumber := SN;
MaxFileNameLen := maxFileName;
//..параметры файловой системы
with info.FileSystemOptions do
begin
CaseSensitive := fsOptions and FS_CASE_SENSITIVE <> 0;
SupportCompression := fsOptions and
FS_FILE_COMPRESSION <> 0;
IsCompressed := fsOptions and FS_VOL_IS_COMPRESSED <> 0;
end;
end;
//Функция отработала успешно
GetDriveInformation := True;
end
else
//Ошибка
GetDriveInformation := False;
end;
Если проанализировать приведенный листинг, то можно увидеть, что функции GetVolumelnf ormation, кроме пути, принадлежащего диску, передается также:
• буфер для метки диска (и длина этого буфера);
• указатель на переменную типа DWORD для записи в нее серийного номера тома диска (присваивается при каждом создании файловой системы, например, после форматирования диска);
• ссылка на переменную типа Cardinal для сохранения в ней максимальной длины компонента пути (имени файла или папки);
• ссылка на переменную типа Cardinal для сохранения в ней набора битовых флагов с некоторыми параметрами файловой системы;
• буфер для названия файловой системы (и его длина).
Как вы могли заметить, результатом работы приведенной в листинге 4.4 функции GetDrivelnf ormation является заполнение структуры (записи) Drivelnf о. Определение этой структуры (а также вложенной в нее структуры, хранящей некоторые извлеченные из битовой маски fsOptions флаги) приводится в листинге 4.5.
Листинг 4.5.
Определение записей для хранения информации о диске
Type
//Запись некоторых параметров о файловой системе
FSOptions = record
CaseSensitive: Boolean; //При уравнении путей
//учитывает регистр
SupportCompression: Boolean; //Файловая система
//поддерживает сжатие
IsCompressed: Boolean; //Диск сжат
end;
//Запись, содержащая информацию о диске
DriveInfo = record
DriveLabel: String; //Метка диска
FileSystemName: String; //Файловая система диска
FileSystemOptions: FSOptions; //Параметры файловой системы
SerialNumber: DWORD; //Серийный номер тома
MaxFileNameLen: Cardinal; //Максимальная длина имени
//файла
end;