Чтение онлайн

на главную - закладки

Жанры

Шрифт:

• FILE_ATTRIBUTE_HIDDEN – скрытый файл или каталог;

• FILE_ATTRIBUTE_NORMAL – означает отсутствие особых атрибутов у файла или каталога (у последнего, естественно, всегда установлен атрибут FILE_ ATTRIBUTE_DIRECTORY);

• FILE_ATTRIBUTE_READONLY – файл или каталог только для чтения;

• FILE_ATTRIBUTE_SYSTEM – системный файл или каталог;

• FILE_ATTRIBUTE_TEMPORARY – временный файл (файловая система стремится по возможности хранить все содержимое открытого временного файла в памяти для ускорения доступа к находящимся в нем данным).

Были рассмотрены основные атрибуты, которые могут быть присвоены объектам файловой системы (файлам и папкам), но не было сказано, как получить или установить атрибуты файла или каталога. Атрибуты можно получить при просмотре содержимого каталога (как в рассмотренных далее функциях поиска). А можно использовать для этого API-функцию GetFileAttributes. Она принимает путь файла (PChar) и возвращает значение типа DWORD (32-битное целое значение), представляющее собой битовую маску. Если функция GetFileAttributes завершается неудачно, то возвращаемое значение равно $FFFFFFFF (-1 при переводе к беззнаковому целому).

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

...

var attrs: DWORD;

begin

attrs := GetFileAttribute(PAnsiChar(\'C:\boot.ini\'));

if (attrs and FILE_ATTRIBUTE_SYSTEM <> 0) then {файл системный};

Атрибуты устанавливаются при помощи API-функции SetFileAttributes. Она принимает два параметра: путь файла или папки (PChar) и битовую маску атрибутов. Возвращает 0 (False) в случае неудачи и ненулевое значение в противном случае.

Поскольку в функцию SetFileAttributes передается маска, хранящая сведения сразу обо всех атрибутах файла или папки, то изменять атрибуты нужно аккуратно (чтобы не удалить установленные ранее). Пример (отрывок программы) «включения» одного и одновременного «выключения» другого атрибута файла приведен в листинге 4.22 (проверка ошибок для простоты не производится).

...

Листинг 4.22.

Изменение атрибутов файла

var attrs: DWORD;

begin

attrs := GetFileAttributes(\'C:\text.txt\');

attrs := attrs or FILE_ATTRIBUTE_HIDDEN; //Установка атрибута «скрытый»

attrs := attrs and not FILE_ATTRIBUTE_ARCHIVE; //Снятие атрибута «архивный»

SetFileAttributes(\'C:\text.txt\', attrs);

Поиск в указанной папке

Поиск в пределах одной папки представляет собой простой перебор всех элементов каталога с отбором тех, имена которых удовлетворяют маске и заданному набору атрибутов. В приведенном ниже примере (листинг4.23) используется API-функция FindFirstFile, которая начинает просмотр заданного каталога, автоматически отсеивая имена файлов и папок, не удовлетворяющи х маске. Функция возвращает дескриптор (THandle), используемый для идентификации начатого просмотра папки при продолжении поиска (в функции FindNextFile).

После окончания просмотра папки вызывается функция FindClose, завершающая просмотр папки. Очень напоминает работу с обычным файлом (открытие, просмотр, закрытие), не так ли?

...

Листинг 4.23.

Поиск в заданной папке

function SearchInFolder(folder, mask: String; flags: DWORD;

names: TStrings; addpath: Boolean = False): Boolean;

var

hSearch: THandle;

FindData: WIN32_FIND_DATA;

strSearchPath: String;

bRes: Boolean; //Если равен True, то нашли хотя бы один

//файл или каталог

begin

strSearchPath := folder + \'\\' + mask;

bRes := False;

//Начинаем поиск

hSearch := FindFirstFile(PAnsiChar(strSearchPath), FindData);

if (hSearch <> INVALID_HANDLE_VALUE) then

begin

//Ищем все похожие элементы (информация о первом элементе

//уже записана в FindData функцией FindFirstFile)

repeat

if (String(FindData.cFileName) <> \'..\') and

(String(FindData.cFileName) <> \'.\') then

//Пропускаем . и ..

begin

if MatchAttrs(flags, FindData.dwFileAttributes) then

begin

//Нашли подходящий объект

if addpath then

names.Add(folder + \'\\' + FindData.cFileName)

else

names.Add(FindData.cFileName);

bRes := True;

end;

end;

until FindNextFile(hSearch, FindData) = False;

//Заканчиваем поиск

FindClose(hSearch);

end;

SearchInFolder := bRes;

end;

Результатом работы функции SearchlnFolder является заполнение списка names именами или, если значение параметра addpath равно True, полными путями найденных файлов и каталогов. Значение параметра flags (битовая маска атрибутов) формируется так же, как для функции SetFileAttributes. Только одновременно можно установить любые интересующие программиста атрибуты. При нахождении хотя бы одного файла или каталога SearchlnFolder возвращает значение True.

В функции поиска проверка соответствия атрибутов найденных файлов и каталогов производится при помощи дополнительной функции MatchAttrs. Код этой функции приведен в листинге 4.24.

...

Листинг 4.24.

Фильтр атрибутов

function MatchAttrs(flags, attrs: DWORD): Boolean;

begin

MatchAttrs := (flags and attrs) = flags;

end;

Может показаться, что проверка из одной строки – слишком слабый аргумент для создания отдельной функции. В рассматриваемом примере отдельная функция MatchAttrs выделена для того, чтобы сделать отсеивание файлов (и папок) по атрибутам более очевидным.

В листинге 4.24 приводится реализация нестрогого фильтра: он принимает файл или папку, если они имеют все установленные в flags атрибуты, независимо от наличия файла или папки дополнительных атрибутов. Так, если мы задали flags:= FILE_ATTRIBUTE_READONLY, то будут найдены как файлы, так и каталоги, а также скрытые, системные и прочие файлы, также имеющие атрибут FILE_ATTRIBUTE_READONLY. Для реализации строгого фильтра можно заменить выражение в функции MatchAttrs простым равенством: flags = attrs.

Возможный результат поиска с использованием функции SearchlnFolder приводится на рис. 4.5.

Рис. 4.5. Поиск в заданной папке

Пример вызова функции SearchlnFolder (для показанного на рис. 4.5 приложения) приведен в листинге 4.25.

...

Листинг 4.25.

Использование функции SearchlnFolder

//Запуск поиска файла в заданной папке

procedure TForm2.Button1Click(Sender: TObject);

var

flags: DWORD;

begin

//Формируем набор атрибутов (по установленным флажкам на форме)

flags := 0;

if (chkDirs.Checked) then flags := flags or FILE_ATTRIBUTE_DIRECTORY;

if (chkHidden.Checked) then flags := flags or FILE_ATTRIBUTE_HIDDEN;

if (chkSystem.Checked) then flags := flags or FILE_ATTRIBUTE_SYSTEM;

if (chkReadOnly.Checked) then flags := flags or FILE_ATTRIBUTE_READONLY;

if (chkArchive.Checked) then flags := flags or

FILE_ATTRIBUTE_ARCHIVE;

lblFound.Caption := \'Поиск…\

lstFiles.Clear;

Refresh;

//Поиск (файлы записываются прямо в список на форме)

if not SearchInFolder(txtFolder.Text, txtMask.Text, flags,

lstFiles.Items)

then

lblFound.Caption := \'Поиск не дал результатов\'

else

lblFound.Caption := \'Найдено объектов: \' +

IntToStr(lstFiles.Count);

end;

Поделиться:
Популярные книги

Туполев

Бодрихин Николай Георгиевич
1327. Жизнь замечательных людей
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Туполев

Пески времени

Шелдон Сидни
Детективы:
триллеры
9.02
рейтинг книги
Пески времени

Бастард Императора. Том 15

Орлов Андрей Юрьевич
15. Бастард Императора
Фантастика:
городское фэнтези
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Бастард Императора. Том 15

Свет горизонта

BlackRaven
1. Свет горизонта
Фантастика:
фэнтези
6.00
рейтинг книги
Свет горизонта

Мажор. Дилогия.

Соколов Вячеслав Иванович
Фантастика:
боевая фантастика
8.05
рейтинг книги
Мажор. Дилогия.

Убивать чтобы жить 7

Бор Жорж
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 7

Закрытые Миры

Муравьёв Константин Николаевич
Вселенная EVE Online
Фантастика:
фэнтези
5.86
рейтинг книги
Закрытые Миры

Афганский рубеж 3

Дорин Михаил
3. Рубеж
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Афганский рубеж 3

Око василиска

Кас Маркус
2. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Око василиска

Тринадцатый XII

NikL
12. Видящий смерть
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
7.00
рейтинг книги
Тринадцатый XII

Сержант. Назад в СССР. Книга 4

Гаусс Максим
4. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сержант. Назад в СССР. Книга 4

Бестужев. Служба Государевой Безопасности. Книга третья

Измайлов Сергей
3. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга третья

Агенты ВКС

Вайс Александр
3. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Агенты ВКС

Группа крови на рукаве

Вязовский Алексей
1. ГК
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.40
рейтинг книги
Группа крови на рукаве