Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Организация поиска файлов и каталогов



В языке Pascal реализованы три специализированные функции, осуществляющие поиск файлов и каталогов в соответствии с критериями, определяемыми программистом. Все три функции должны работать в тесном союзе друг с другом и вызываться только в определенной последовательности. Первая из функций предназначена для инициализации поиска и нахождения первого файла, соответствующего нашим требованиям:

 

functionFindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;

 

В первом аргументе метода необходимо указать каталог, где будет осуществляться поиск, и маску поиска. Например, маска ‘C: \Mydir\*.txt’ задает поиск всех файлов с расширением txt в каталоге ‘C: \Mydir’. Второй аргумент определяет атрибуты искомых файлов (см. табл. 4.5). Один файл может обладать одним и более атрибутами.

Если файл успешно найден, функция вернет нулевое значение, а данные о найденном файле окажутся в переменной F типа TSearchRec.

 

Type

TSearchRec = recordTime:

Integer; //дата файла

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

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

Name: TFileName; //имя файла

ExcludeAttr: Integer; //не документировано

FindHandle: THandle; //дескриптор файла

FindData: TWin32FindData; //структура Win API с дополнительной информацией

end;

Вторая функция FindNext() является логическим продолжением метода FindFirst(). Задача метода – поиск оставшихся файлов. При нахождении файла функция возвращает нулевое значение и записывает данные в переменную F.

 

functionFindNext(var F: TSearchRec): Integer;

 

По завершении поиска метод FindClose() обязан освободить использованные ресурсы:

 

procedure FindClose(var F: TSearchRec);

 

Теперь обратимся к примеру, демонстрирующему способ сбора данных обо всех файлах и каталогах, размещенных в корне диска C: \. Поиск данных осуществляется в цикле до тех пор, пока метод FindNext() не вернет отличное от нуля значение.

 

var F: TSearchRec;

Begin

ifFindFirst('c: \*.*', faAnyFile, F)=0 then

Repeat

if (F.Attr and faDirectory) < > 0 then //если это каталог, то отобразим только имя

WriteLn(F.Name)

else//это файл, выводим более подробную информацию

WriteLn(F.Name, #9, F.Size, #9, DateTimeToStr(FileDateToDateTime(F.Time)));

until FindNext(F)< > 0;

FindClose(f);

ReadLn;

End.

При организации поиска стоит обратить внимание на некоторые особенности проверки принадлежности определенного атрибута набору атрибутов найденного файла. Для этого мы выясняем результат комбинации атрибутов файла и нашего атрибута при помощи оператора and: (F.Attr and faDirectory) < > 0. Если возвращено ненулевое значение, то атрибут входит в набор. Говоря о поиске, стоит упомянуть еще один метод, проверяющий перечень путей к искомому файлу и выбирающий верный:

 

function FileSearch (const Name, DirList: string): string;

 

Здесь в параметре Name указывается имя искомого файла, а в параметре DirList передается список путей, разделенных точкой с запятой. Если в перечне путей не окажется правильного, метод вернет пустую строку:

 

FilePath: =FileSearch('comctl32.dll', 'C: \; C: \Windows; C: \Windows\System');

 

Управление каталогами

Набор методов, предназначенных для работы с каталогами, не столь впечатляющий по сравнению с набором процедур и функций для работы с файлами. Однако и этот золотой минимум позволяет решать все возникающие перед программистом задачи.

 

Таблица 4.6. Функции для работы с каталогами

Функция Описание
procedure GetDir(Drive: Byte; var S: string);     function GetCurrentDir: string;   function SetCurrentDir(const Dir: string): Boolean;   procedure ChDir(S: string);   function CreateDir(const Dir: string): Boolean; function DirectoryExists(Name: string): Boolean;   function RemoveDir(const Dir: string): Boolean;   functionForceDirectories(Dir: string): Boolean; Возвращает текущий каталог на диске Drive. Номер диска выбирается аналогично функции DiskFree().   Возвращает текущий каталог.   Устанавливает каталог Dir текущим. В случае успеха возвращает true.   Выбирает новый текущий каталог.   Создает новый каталог и возвращает true в случае успеха. Проверяет наличие каталога Name и возвращает true в случае успеха.   Удаляет пустой каталог Dir. В случае успеха возвращает true.   Создает все каталоги, определенные в параметре Dir. В случае успеха возвращает true.

Как всегда существенную помощь нам окажут функции операционной системы. В первую очередь следует упомянуть информационные методы, сообщающие нам «где и что лежит».

 

FunctionGetWindowsDirectory(Buffer: PChar; Size: Integer): Integer;

Function GetSystemDirectory (Buffer: PChar; Size: Integer): Integer;

Function GetTempPath(Size: Integer; Buffer: PChar): Integer;

Function GetCurrentDirectory(Size: Integer; Buffer: PChar): Integer;

 

Функции возвращают пути соответственно к каталогу Windows, системному каталогу, каталогу временных файлов и текущему каталогу.

 

var Buf: array [0..MAX_PATH-1] of Char;

Begin

GetWindowsDirectory(Buf, SizeOf(Buf));

WriteLn(Buf); ReadLn;

end;

 

Если методы выполнились без ошибок, то они возвратят количество символов в пути, в противном случае вы получите нулевое значение.

Напоминаю, что для преобразования строки из формата, привычного для Windows, в формат AnsiString следует использовать метод StrPas():

 

S: =StrPas(Buf);

 

Для переименования или перемещения каталога используйте метод MoveFile(), рассмотренный ранее, или изучите еще более «продвинутые» версии – MoveFileEx() и MoveFileWithProgress().

 

Работа с дисками компьютера

Говоря о дисках, первое, что нас может заинтересовать, – сколько на нем осталось свободного места. Для этого в языке Pascal реализована функция:

 

function DiskFree(Drive: Byte): Int64;

 

Функция возвращает количество свободного места на диске в байтах. Параметр Drive требует передачи номера диска. Например, 0 = текущий, 1 = A, 2 = B, 3 = С и т. д. Если метод не в состоянии выяснить размер свободного места на диске, он возвращает –1.

Общий размер диска сообщает метод DiskSize(). Выбор номера диска аналогичен методу DiskFree().

 

functionDiskSize(Drive: Byte): Int64;

 

При работе с дисками неоценимую поддержку программисту оказывает Windows API. Кстати, оба рассмотренных выше метода в тайне от нас пользуются услугами функции Windows API GetDiskFreeSpaceEx(). Преимущество этого метода в том, что он всего за один вызов делает то, с чем DiskFree() и DiskSize() справляются только вдвоем. А именно он возвращает количество свободных байт (FreeBytesAvailable), доступных в данный момент пользователю, и общее количество байт на диске (TotalNumberOfBytes). При этом имя диска передается в привычном виде, например C: \, а не в виде цифры, как в случае функций языка Pascal.

 

Function GetDiskFreeSpaceEx(Drive: PChar; FreeBytesAvailable, TotalNumberOfBytes,

TotalNumberOfFreeBytes: INT64): Boolean;

 

Если метод выполнился удачно, он возвратит true. Четвертый параметр функции не используется, и вместо него передавайте указатель в никуда – nil. Еще один весьма полезный метод из обоймы операционной системы Windows расскажет нам о типе диска, подключенного к системе:

 

Function GetDriveType (Drive: PChar): Integer;

 

Метод требует указания всего одного параметра – указателя на строку с именем диска. Результат возвращается в соответствии с табл. 4.7.

Таблица 4.7. Константы типа диска

Значение Описание
DRIVE_REMOVABLE DRIVE_FIXED DRIVE_REMOTE DRIVE_CDROM DRIVE_RAMDISK Невозможно определить тип диска. Корневой каталог отсутствует. Съемный диск. Жесткий диск. Удаленный (сетевой) диск. Привод CD. Диск в оперативной памяти.

Для закрепления пройденного материала реализуем скромный пример, посвященный изучению состава дисков компьютера.

 

program...;

{$APPTYPE CONSOLE}

uses SysUtils, Windows;

const ByteInMb=1048576; // 220, именно столько байт в 1 Мбайт

var Ch: CHAR;

iDriveType: Integer;

sDriveType, sSize, sFree: string;

AllBytes, FreeBytes: INT64;

Begin

forCh: ='A' to 'Z' do

Begin

iDriveType: =GetDriveType(PChar(Ch + ': \'));

if iDriveType< =1 then Continue; //если диск не обнаружен, пропускаем шаг

case iDriveType of

DRIVE_REMOVABLE: sDriveType: ='Removable';

DRIVE_FIXED: sDriveType: ='Fixed';

DRIVE_REMOTE: sDriveType: ='Network';

DRIVE_CDROM: sDriveType: ='CD-ROM';

DRIVE_RAMDISK: sDriveType: ='RAM'

else sDriveType: ='Unknown'

end;

sDriveType: ='['+sDriveType+']';

if GetDiskFreeSpaceEx(PChar(Ch + ': \'), FreeBytes, AllBytes, nil)=True then

Begin

sSize: =Format('Size: %d.%d Mb', [AllBytes div ByteInMb,

AllBytes mod ByteInMb]);

sFree: =Format('Free: %d.%d Mb', [FreeBytes div ByteInMb,

FreeBytes mod ByteInMb]);

End

else sSize: =''; sFree: ='';

WriteLn(Ch+': \',

sDriveType,

#9, sSize, #9,

sFree);

end;

ReadLn;

End.

Задача рассматриваемой программы – собрать сведения обо всех дисках, установленных на компьютере, выяснить их тип, размер и наличие свободного пространства. Сведения о размерах выводятся не в байтах, а в мегабайтах; для этого осуществляется деление на константу ByteInMb, содержащую количество байт в одном мегабайте (220=1048576). Сведения о диске вашего компьютера пополнит еще одна функция из пакета Windows API:

 

FunctionGetVolumeInformation(

Drive: PChar; // указатель на строку с именем диска

VolumeNameBuffer: PChar; // буфер, в который будет записано имя тома

VolumeNameSize: DWord; // размер буфера с именем тома

VolumeSerialNumber: DWord; // указатель на серийный номер тома

MaximumComponentLength: DWord; // максимальное число символов

// в имени файла

FileSystemFlags: DWord; // указатель на флаги файловой системы

FileSystemNameBuffer: PChar; // буфер с названием файловой системы

FileSystemNameSize: DWord // размер буфера с названием

// файловой системы

): Integer;

 

В первом аргументе требуется указать имя диска (не забыв про двоеточие и слэш), о котором нам хочется получить данные. Во все остальные параметры требуется подставить соответствующие массивы и переменные, в которые функция с радостью вернет результаты анализа диска. Если все сложится успешно, метод вернет любое ненулевое значение.

 

uses SysUtils, Windows;

var VolumeNameBuffer, FileSystemNameBuffer: array [0..MAX_PATH-1] of Char;

SerNum, MaxLen, NotUsed, VolFlags: DWORD;

Begin

GetVolumeInformation(PChar('C: \'), VolumeNameBuffer,

DWord(Sizeof(VolumeNameBuffer)),

@SerNum,

MaxLen,

VolFlags,

FileSystemNameBuffer,

DWord(SizeOf(FileSystemNameBuffer)));

WriteLn('Drive C: \ information');

WriteLn('Volume label: ', VolumeNameBuffer);

WriteLn('File system: ', FileSystemNameBuffer);

WriteLn('Serial number: ', SerNum);

WriteLn('Maximum length: ', MaxLen);

ReadLn;

End.

В примере осталось нераскрытым содержание параметра FileSystemFlags. Это флаг или комбинация флагов, выявляющая некоторые особенности файловой системы, например такие, как поддержка регистра в названиях файлов, возможность сжатия тома и т. п. Более полную информацию можно получить из справочной системы.

В заключение познакомимся еще с одной функцией Windows API, которая предназначена для смены метки тома:

 

Function SetVolumeLabel(Drive, VolumeName: PChar): Boolean;

 

Название тома передается через параметр VolumeName.

 

Резюме

 

Порядок работы с файлом, а также перечень и особенности вызова методов определяются типом файла. Различают три типа файлов: текстовый, типизированный и двоичный (нетипизированный). Действия, связанные с чтением и записью данных, называются операциями ввода-вывода. Помимо операций ввода-вывода среда Delphi и операционная система Windows предоставляют методы для управления файлами и каталогами. Например, процедуры и функции, предназначенные для поиска файла, получения информации о файле, для удаления, копирования и перемещения файла.


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-03-17; Просмотров: 952; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.05 с.)
Главная | Случайная страница | Обратная связь