Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование лекции.doc
Скачиваний:
49
Добавлен:
12.11.2019
Размер:
5.53 Mб
Скачать

18.2. Получение сведений о дисках

При записи файла на диск (особенно если это сменный носитель – дискета или флэшка) желательно сначала проверить, а хватит ли свободного места? Для этого предназначены функции 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.

18.3. Получение сведений о файлах

Если ваша программа использует какие-либо файлы данных, настроек и т.п., всегда есть вероятность, что при очередном запуске нужного файла на диске не окажется – то ли пользователь стер по ошибке, то ли вирус потрудился. Если такую ситуацию не предусмотреть, программа "свалится" с выдачей противного сообщения " Access Violation", а автора программы и его маму будут поминать нехорошими словами.

Крайне желательно перед открытием файла проверять, существует ли он на диске. Делается это очень просто:

для файла:

FileExists(имя_файла)

для директории:

DirectoryExists(имя_директории);

Проверка может выглядеть, например, так:

IF NOT(FileExists

(ExtractFilePath(Application.ExeName)+'data.dat') THEN

BEGIN

MessageDlg('Пропал файл data.dat!',mtError,[mbOK],0);

Close

END;

Обратите внимание на конструкцию ExtractFilePath(Application.ExeName). В свойстве Exename глобального объекта Application всегда хранится имя exe-файла нашей программы с полным путем к нему. Функция ExtractFilePath извлекает только путь к exe-файлу. Таким образом, всегда можно узнать, из какой директории запущена программа, и где искать необходимые для ее работы файлы.

У файла есть много параметров – размер, дата и время создания, атрибуты. Их можно "выковыривать" по одному при помощи кучи функций типа GetFileSize, GetAttr и т.д., которые остались в Delphi как тяжелое наследство старого Паскаля. Но есть способ лучше! В языке предусмотрен специальный тип данных TSearchRec для хранения всех сведений о файле в одной переменной:

TSearchRec = record

Time: Integer; // дата и время создания

Size: Integer; // размер в байтах

Attr: Integer; // атрибуты файла

Name: TFileName; // имя файла с расширением

end;

Все поля записи заполняются при помощи процедуры

FindFirst(имя_файла, атрибут, переменная_типа_TSearchRec)

Параметр атрибут указывает, с файл какими атрибутами нужно искать. Его возможные значения:

faReadOnly ­- только для чтения;

faHidden ­- скрытый файл;

faSysFile ­- системный файл;

faVolumeID ­- метка диска;

faDirectory ­- директория;

faArchive ­- обычный файл;

faAnyFile ­- любой файл.

Например:

VAR s:TSearchRec;

with OpenDialog1 do

if Execute THEN

BEGIN

FindFirst(filename,faAnyFile,s);

Label1.Caption:='Размер файла '+IntToStr(s.Size)+'Кб'

END;

Для работы с датой и временем создания файла значение в поле Time надо преобразовать при помощи функции с длинным названием FileDateToDateTime:

Label1.Caption:=DateTimeToStr(FileDateToDateTime(s.Time))