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


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



В языке 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; Просмотров: 53; Нарушение авторского права страницы


lektsia.com 2007 - 2017 год. Все права принадлежат их авторам! (0.105 с.) Главная | Обратная связь