MS-DOS для программиста© Александр Фролов, Григорий ФроловТом 19, М.: Диалог-МИФИ, 1995, 253 стр. 3.3. Поиск в каталогахЧасто перед программистом стоит задача определения содержимого каталога. При описании логической структуры диска мы приводили текст программы, выводящей на экран содержимого корневого каталога и других каталогов. Эта программа использовала загрузочный сектор логического диска и таблицу размещения файлов . Вы можете использовать такой способ, однако если вам не требуется информация о номерах начальных кластеров файлов и дескрипторы удаленных файлов, лучше применить специальные функции MS-DOS, предназначенные для поиска файлов в каталогах. Это функции 4Eh и 4Fh. Указанные выше функции используются вместе следующим образом: Вначале вызывается функция 4Eh для поиска в каталоге файла, соответствующего образцу. В образце можно использовать символы "?" и "*", которые означают, соответственно, один любой символ и любое количество любых символов. Информация о найденном файле располагается в специальной области, распределенной каждой работающей программе - области DTA . Затем для поиска остальных файлов, удовлетворяющих заданному ранее образцу, в цикле вызывается функция 4Fh. Условие завершения цикла - отсутствие в каталоге указанных файлов. Функция 4Eh вызывается следующим образом:
Функция 4Fh имеет следующие параметры вызова:
Обе функции устанавливают флаг переноса в том случае, когда каталог не содержит файлов, удовлетворяющих заданному критерию поиска. Для работы с областью DTA в составе MS-DOS имеются две функции. Это функция 2Fh, позволяющая получить адрес области DTA (она возвращает этот адрес в регистрах ES:BX), и функция 1Ah, предназначенная для установки своей области DTA (адрес новой области DTA должен быть указан в регистрах DS:DX). Напомним, что по умолчанию область DTA занимает 128 байт в префиксе сегмента программы PSP со смещением 80h. В случае успешного поиска функции 4Eh и 4Fh
помещают в DTA информацию о найденных файлах в
следующем формате:
Номер начального кластера, распределенного файлу или каталогу, невозможно получить с помощью функций 4Eh и 4Fh. Стандартная библиотека Borland C++ содержат две функции, предназначенные для сканирования каталогов. Это _dos_findfirst и _dos_findnext . Приведем прототипы этих функций, описанные в файле dos.h: int _dos_findfirst (char *pattern, struct find_t *found, unsigned attr); int _dos_findnext (struct find_t *found); В этих функциях параметр pattern определяет образец для поиска файлов, параметр attr (атрибуты файла) используется в качестве дополнительного критерия поиска. Параметр found представляет собой указатель на структуру, в которую будет записываться информация о найденных файлах. Эта структура определена в файле dos.h:
struct find_t
{
char reserved[21]; // зарезервировано для DOS
char attrib; // атрибуты файла
unsigned wr_time; // время изменения файла
unsigned wr_date; // дата изменения файла
long size; // размер файла в байтах
char name[13]; // имя файла и расширение
};
Программа DIRLISTПриведем текст программы просмотра содержимого каталога DIRLIST (листинг 3.3). Программа принимает из командной строки параметр - образец для показа файлов. Если вы укажете параметр *.*, будет выведена информация обо всех файлах. Можно задавать полный путь: c:\*.*. Листинг 3.3. Файл dirlist\dirlist.cpp
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
void print_info(struct find_t *find);
char *time_conv(unsigned time, char *char_buf);
char *date_conv(unsigned date, char *char_buf);
#pragma argsused
int main(int argc, char *argv[])
{
struct find_t find;
// Находим первый файл, удовлетворяющий критериям поиска.
// В качестве критерия используем образец, полученный
// из командной строки. Для поиска используем
// файлы с любыми атрибутами
if(!_dos_findfirst (argv[1], 0xffff, &find))
{
printf("\n"
"\nИмя файла Аттр. Дата Время Размер"
"\n------------ ----- ---------- -------- ------");
// Выводим информацию о первом найленном файле на экран
print_info(&find);
}
else
{
printf("Задайте образец для поиска файлов !");
return(-1);
}
// Выводим информацию об остальных найденных файлах
while(!_dos_findnext (&find)) print_info( &find );
return(0);
}
// Функция для вывода информации о найденных файлах
void print_info(struct find_t *pfind)
{
char timebuf[10], datebuf[12];
// Преобразуем формат даты и времени
// последнего изменения файла
date_conv(pfind->wr_date, datebuf);
time_conv(pfind->wr_time, timebuf);
// Выводим содержимое дескриптора файла
printf("\n%-12s",pfind->name);
printf(" %02X %8s %8s %8ld ",
pfind->attrib, datebuf, timebuf, pfind->size);
}
// Функция преобразования формата времени
char *time_conv(unsigned t, char *buf)
{
int h, m;
h = (t >> 11) & 0x1f;
m = (t >> 5) & 0x3f;
sprintf(buf, "%2.2d:%02.2d:%02.2d",
h, m, (t & 0x1f) * 2);
return buf;
}
// Функция преобразования формата даты
char *date_conv(unsigned d, char *buf)
{
sprintf(buf, "%2.2d.%02.2d.%04.2d",
d & 0x1f,(d >> 5) & 0x0f, (d >> 9) + 1980);
return buf;
}
|

