КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Программный опрос файловой системы
Особенности строения файловых систем для Unix Принципиальной особенностью файловых систем для Unix является хранение минимальной информации в записях оглавления. Так, в современной расширенной файловой системе для Linux, называемой в сокращении ext2, структура записи каталога описывается структурой struct dir {unsigned long inode_num; unsigned short rec_len; unsigned short name_len; char name[256]; /* between 0 and 256 chars */ }; В самой старой файловой системе для Unix, созданной еще в 70-х годах XX века, запись каталога занимала всего 16 байтов, из которых 14 байтов предназначались под имя файла (или каталога), а два оставшихся хранили значение индексного узла (inode). В современном решении запись каталога имеет переменную длину, определяемую для каждой записи полем rec_len и содержит имя длинной до 255 символов, причем поле name_len задает действительное значение этого имени. Такое решение связано со стремлением, как допускать очень длинные имена и в то же время не делать очень большими записи каталога. По существу, поля rec_len, name_len – вспомогательные, и запись каталога несет все ту же содержательную информацию. Вся информация о файле (каталоге), за исключением его имени в текущем каталоге, хранится в специализированной структуре файловой системы, называемой индексным узлом (inode). Именно в нем хранится время создания файла (каталога), время последней модификации, время последнего доступа, число ссылок на файл, размер файла. Более подробная информация представлена в описании структуры inode: typedef struct { unsigneg short i_mode; /* File mode */ unsigneg short i_uid; /* Owner Uid */ unsigneg long i_size; /* Size in bytes */ unsigneg long i_atime; /* Access time */ unsigneg long i_ctime; /* Creation time */ unsigneg long i_mtime; /* Modification time */ unsigneg long i_dtime; /* Deletion Time */ unsigneg short i_gid; /* Group Id */
unsigneg short i_links_count; /* Links count */ unsigneg long i_blocks; /* Blocks count */ unsigneg long i_flags; /* File flags */ unsigneg long i_reserved1; /* Reserved 1 */ unsigneg long i_block[15]; /* Pointers to blocks */ unsigneg long i_version; /* File version (for NFS) */ unsigneg long i_file_acl; /* File ACL */ unsigneg long i_dir_acl; /* Directory ACL */ unsigneg long i_faddr; /* Fragment address */ unsigneg char i_frag; /* Fragment number */ unsigneg char i_fsize; /* Fragment size */ unsigneg long i_reserved2[2]; /* Reserved 2 */ } inode;
Операции по получению данных из файлов и запись в файлы составляют одну из основ программирования и в применении к отдельным ОС уже рассматривались в гл. 2. Кроме этих общеупотребительных функций нередко возникает проблема нахождения в некотором каталоге файлов, удовлетворяющих определенным условиям. В частности, иногда требуется получение информации, какие файлы находятся в некотором каталоге. Для решения подобных задач в операционные системы включены системные функции просмотра содержимого каталогов. В ОС Unix операции с каталогом строятся подобно операциям с типизированными файлами, используемыми в Паскале, а именно, вводится указатель на структуру данных, описывающую каталог. Эта структура описана в заголовочном файле dirent.h и имеет имя DIR. Указатель на эту структуру данных используется для получения значения от функции opendir, имеющей прототип DIR* opendir(char *dirname), где единственный аргумент задает имя того каталога, из которого требуется получить информацию. При невозможности открыть указанный аргументом каталог функция возвращает значение NULL. Дальнейшие действия выполняются системной функцией с прототипом struct dirent *readdir(DIR* dirptr), с аргументом, полученном от предыдущей функции. Каждое выполнение вызова readdir() возвращает указатель на содержимое структуры типа dirent, содержащей информацию об очередном элементе каталога. Эта структура данных описана также в заголовочном файле dirent.h. В последней структуре два основных поля, которые заданы в ней как ino_t d_ino; /* Номер индексного дескриптора */
char d_name[ ]; /* Имя файла, заканчивающегося нулевым байтом*/ При использовании этих полей каталога следует иметь в виду, что нулевое значение поля d_ino вполне возможно у используемого каталога и обозначает неиспользуемую запись в каталоге (обычно по причине удаления информации о фРйле из данного каталога).
После окончРния использования указателя нР каталог, полученный от функции opendir(), следует выполнить закрытие доступа к каталогу и освобождение ресурсов вызовом функции с прототипом int closedir(DIR* dirptr), Вспомогательной функцией работы с каталогами служит описываемая прототипом void rewinddir(DIR* dirptr), которая позволяет вернуться к началу каталога с целью чтения его опять с самого начала. Применение описанных функций демонстрирует программа примера, приведенного в листинге 6.8.1.
#include <unistd.h> #include <dirent.h> #include <string.h>
int main() {DIR *dp; struct dirent *de; int len, rc;
dp=opendir("."); if (dp= =NULL) {printf("No those files\n"); exit(1);} while (de=readdir(dp)) { if (de->d_ino!= 0) {len=strlen(de->d_name); if (!strcmp(".c",(de->d_name)+len-2)) printf("%s\n",de->d_name); } } closedir(dp); return 0; } Листинг 6.8.1. Программный доступ к информации каталога в Unix
Эта программа последовательно читает все записи текущего каталога (обозначаемого символом '.'), и если запись не пуста, то проверяет, не оканчивается ли имя файла, заданного в этой записи на цепочку символов ".c". При совпадении выполняется вывод имени файла на экран. В операционных системах типа Windows и OS/2 разработчики включили проверку условия для имени файла в действия соответствующей системной функции. В этих ОС основных функций, работающих с содержимым каталогов, – две: функция поиска первого файла по задаваемому условию и функция поиска следующего файла по тому же условию. Само условие задается как метанотация, т.е. записью совокупности файлов с помощью метасимволов * и? в соответствующем аргументе имени файла. Использование этих метасимволов полностью совпадает с традиционным их применением в командах операционной системы, восходящим к правилам командного интерпретатора Unix. В Windows для поиска первого файла в каталоге служит функция с прототипом HANDLE FindFirstFile(char *metaname, WIN32_FIND_DATA *FindFileData), где аргумент metaname задает метанотацию файла в текущем каталоге или в явно заданном в аргументе каталоге, а второй аргумент задается адресом (указателем на) экземпляра структуры данных, куда должна быть помещена служебная информация о файле. Поля этой структуры данных, описывающей кроме имени файла еще и вспомогательную информацию, дают среди прочего время последней коррекции и последнего доступа (а также ряд других параметров). Наиболее значимым является поле с именем cFileName, описывающее имя файла массивом символов. При неудаче функция возвращает значение INVALID_HANDLE_VALUE (равное -1), в противном случае она возвращает специальный хэндл, предназначенный для использования только в функции продолжения поиска и закрытия этого хэндла. По существу, упомянутый хэндл соответствует хэндлу каталога, который получается от функции открытия каталога в Unix.
Для поиска следующих файлов, удовлетворяющих той же метанотации, что была задана при выполнении функции FindFirstFile, в Windows служит функция с прототипом BOOL FindNextFile(HANDLE hFindFile, WIN32_FIND_DATA *FindFileData), где аргумент hFindFile должен быть получен от функции FindFirstFile, а второй аргумент задает экземпляр структуры для размещения служебной информации о файле и уже рассматривался для предыдущей функции. Последняя функция возвращает значение TRUE, если находит очередной файл в текущем каталоге, удовлетворяющий метанотации, в противном случае она возвращает значение FALSE. В завершение работы с каталогом должна вызываться функция с прототипом BOOL FindClose(HANDLE hFindFile), которая закрывает хэндл, ранее полученный от функции FindFirstFile. Следующая программа для Windows, приведеная в листинге 6.8.2, демонстрирует поиск в текущем каталоге файлов, которые имеют расширение ".c", с выводом их имен на экран. По существу эта программа полностью соответствует программе в листинге 6.8.1.
#include <stdio.h> #include <windows.h>
int main() {HANDLE fdirsearch; WIN32_FIND_DATA dan; BOOL rc;
fdirsearch=FindFirstFile("*.c", &dan); if (fdirsearch= =INVALID_HANDLE_VALUE) {printf("No those files\n"); exit(1);} do { printf("%s\n",dan.cFileName); rc=FindNextFile(fdirsearch, &dan); } while(rc!=FALSE); FindClose(fdirsearch); return 0; } Листинг 6.8.2. Программный доступ к информации каталога в Windows
Для вспомогательных действий по переустановке текущего каталога предназначена в Windows функция с прототипом BOOL SetCurrentDirectory(char *PathName)), а также функция с прототипом DWORD GetCurrentDirectory(DWORD BufferSize, char *Buffer), которая позволяет запомнить в символьном массиве полное имя текущего каталога.
Дата добавления: 2014-01-05; Просмотров: 350; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |