При записи файла на диск (особенно если это сменный носитель – дискета или флэшка) желательно сначала проверить, а хватит ли свободного места? Для этого предназначены функции DiskFree(n) и DiskSize(n). Первая возвращает объем свободного места на диске в килобайтах, вторая – общий размер диска в килобайтах. Функции возвращают "очень длинное" 64-битное целое число типа INT64. Параметр n - целое число, которым кодируется диск: 0 – текущий диск, 1 – дисковод А:, 3 – диск С: и т.д. Например, можно вывести информацию о диске:
FUNCTION FreeSpace(disk:STRING):STRING;
VAR d:BYTE;
BEGIN
d:=ORD(disk[1])-ORD('A')+1;
Result:='Всего:'+FloatToStrF(DiskSize(d)/ 1073741824,
ffFixed,10,2)+' Гб, свободно '+
FloatTostrF(DiskFree(d)/ 1073741824,ffFixed,10,2)+ 'Гб'
END;
На вход функции FreeSpace подается имя диска как текстовая строка, скажем, 'D:\'. Для преобразования текстового имени диска в его порядковый номер используется следующий прием: вычисляется код буквы диска ORD(d[1]) и из него вычитается код буквы А. Если имя диска A:\, то после вычитания получим 0, С:\ - получим двойку и т.д. А если к этой разности добавить единицу, то диску A:\ будет соответствовать 1, диску B:\ - 2… что и требуется. Константа 1073741824=10243 служит для перевода килобайт в гигабайты.
А как узнать, какие вообще логические диски в системе? Проще простого:
PROCEDURE FindDisks(s:TStrings);
VAR c:CHAR;
BEGIN
s.Clear;
FOR c:='C' TO 'Z' DO
IF DirectoryExists(c+':\') THEN
s.Add(c+':')
END;
Выполняем цикл по всем возможным именам дисков от C: до Z:. Дисководы не трогаем, чтобы не пугать пользователя. Если путь к очередному диску найден, записываем имя диска в динамический массив текстовых строк. Например, при помощи такой функции можно вывести список дисков в компонент TComboBox:
procedure TForm1.Button1Click(Sender: TObject);
begin
FindDisks(ComboBox1.Items)
end;
А как определить, с чем мы имеем дело – с дисководом, винчестером, сетевым диском? Для этого предназначена функция GetDriveType, встроенная в API-функции Windows. Рассмотрим пример:
FUNCTION DriveType(s:STRING):STRING;
BEGIN
CASE GetDriveType(PCHAR(s)) OF
1: Result:='Нет диска';
DRIVE_REMOVABLE: Result:='Дисковод или Flash';
DRIVE_FIXED: Result:='Жесткий диск';
DRIVE_REMOTE: Result:='Cетевой диск';
DRIVE_CDROM: Result:='CD';
DRIVE_RAMDISK: Result:='Виртуальный диск'
ELSE
Result:='Не могу определить'
END;
END;
Так как все функции API Windows работают с указателями на текстовые строки, обычную паскалевскую строку типа STRING приходится преобразовывать в указатель при помощи операции PCHAR.