Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
28
Добавлен:
17.04.2013
Размер:
64 Кб
Скачать

Московский Институт Электронной Техники

Кафедра ИПОВС

Лабораторная работа

Работа с каталогами файловой системы на языке С++

Цель работы:

  • изучить возможности работы с каталогами файловой системы;

  • ·получить практические навыки программирования задач с использованием функций работы с каталогами файловой системы.

Теоретические сведения

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

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

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

#include <dir.h>

#include <dos.h>

Функции поиска файла или каталога на диске findfirst

Прототип функции:

Int findfirst ( char *pathname,

struct ffblk *buffer,

int attrib);

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

Аргумент pathname – это адрес строки, содержащей необязательный спецификатор устройства и полное имя искомого файла (включающего имя пути). Имя файла может содержать регулярное выражение (символы ? или * с тем же значением, что и в командной строке MS-DOS).

Когда заданный файл найден, происходит заполнение структуры, адрес который задается параметром buffer, информацией о каталоге.

Синтаксис структуры ffblk:

Struct ffblk

{

char ff_reserverd[21]; //зарезервировано DOS

char ff_attrib; //найденный атрибут

int ff_ftime; //время создания

int ff_fdate; //дата создания

long ff_fsize; //размер

chat ff_name[13]; // найденное имя

};

Поле ff_fdateсодержит дату создания файла или каталога в следующем в виде:

с 0 по 4 бит - число

с 5 по 8 бит - месяц

с 9 по 15 бит год.

Для получения числа даты создания необходимо значения поля ff_fdateпобитово умножить на восьмеричное число 37: ff_fdate & 037.

Для получения месяца даты создания необходимо преобразовать данное поле следующим образом: (ff_fdate & 0740) >> 5.

Если требуется узнать год создания файла или каталога, то поле ff_fdateнеобходимо преобразовать следующим образом: ((ff_fdate & 0177000) > 9)+1980.

Поле ff_ftimeсодержитвремясоздания файла или каталога в следующем виде:

с 0 по 4 бит - секунды

с 5 по 10 бит - минуты

с 11 по 15 бит часы.

Для получения значения минут времени создания необходимо выполнить операцию: (ff_ftime & 03740) >> 5, а для нахождения значений часа: (ff_ftime& 0174000) >> 11.

Параметр attrib– байт атрибутов файла MS-DOS, используемый при выборе допустимых файлов в поиске.

Параметр attrib может принимать значения:

a _normal -обычный файл (чтение/запись)

fa_rdonly - только чтение

fa_hidden - скрытый файл

fa_system - системный файл

fa_lable - метка тома

fa_direct - каталог

fa_arch - архив.

Поиск производится только в пределах каталога.

Данная функция возвращает значение 0 при успешном поиске и –1, если файл или каталог не найдены.

Функция продолжения поиска файла findnext.

Прототип функции:

Int findnext (struct ffblk *buffer);

Функция findnext используется для поиска следующего файла, имя которого подходит под регулярное выражение, заданное как аргумент для последнего вызова функции findfirst. Структура, заполняемая при вызове функции, содержит информацию, необходимую для продолжения поиска. На каждый последующий вызов функции findnext будет возвращаться новое имя файла до тех пор, пока не возникнет такая ситуация, что не останется более ни одного файла, имя которого подходило бы под заданное регулярное выражение. Поиск происходит только в пределах каталога.

Функция возвращает значение 0 при успешном поиске и значение –1, если файл не найден.

Пример использования функций findfirst и findnext.

Выведем на экран все файлы с расширением *.срр из текущего каталога.

#include <dir.h>

#include <dos.h>

#include <conio.h>

#include <stdio.h>

void main()

{

clrcsr(); // очистка экрана

ffblk f; // структура ffblk

char *path=new char[20]; // регулярное выражение

strcpy(path, “*.cpp”);

/* поиск первого файла с расширение *.cpp */

int a=findfirst(path, &f, FA_DIRECT);

while(!a) // цикл пока файл не найден

{

puts(f.ffname); // печать имени файла

a=findnext(&f); // продолжить поиск

}

} //конец функции main

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

Строка аргументов.

Как и любая другая функция, написанная на языке С++, функция mainможет иметь аргументы. Эти аргументы передаются функции main через командную строку. В этом случае функция main должна иметь вид:

Void main ( int argc, char *argv[])

Параметр argcопределяет общее количество передаваемых аргументов.

Параметр argv представляет собой массив адресов, каждый элемент которого указывает на строковое представление соответствующего по порядку аргумента, передаваемого программе. Первый элемент массива argv(т.е.argv[0]) всегда содержит имя программы, по которому она была вызвана. Этот элемент всегда заполнен, поэтому значение argc всегда равно, по крайней мере, 1.

Задать значение аргументов командной строки можно либо из MS-DOS, например: D> prim.exe test.txt, где prim.exe имя файла исполняемой программы, а test.txt имя второго аргумента; либо из интегрированной среды Borland 3.1:пункт меню Run, подпункт Arguments.

Пример программирования

Пример 1.

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

Текст программы

#include <dir.h>

#include <dos.h>

#include <conio.h>

#include <stdio.h>

#include <string.h>

void main (int argc, char argv[])

{

struct DIR {

char name[13]; //имя файла

long size; //размер

int data; // дата создания

int time; //время создания

};

struct list{

DIR inf; // информация о файле

list *next; // адрес следующей информации

};

/* описание переменных */

list *Dir=NULL, *pntr, *p, *min;

DIR dir;

Ffblk ff;

Char *path=new char[35];

/* формирование имени файла для поиска */

if (argc == 1) strcpy (path. “*.cpp”);

else {

strcpy(path,”*.”);

strcpy(path,argc[1]);

}

/* поиск файлов и заполнение односвязанного списка информацией о файлах */

int a=findfirst(path, &ff, FA_DIRECT && FA_ARCH);

while(!a)

{ pntr= new list;

if (Dir == NULL) Dir =pntr;

else p->next=pntr;

strcpy(pntr->inf.name, ff.ff_name);

pntr->inf.size=ff.ff_fsize;

pntr->inf.data=ff.ff_fdata;

pntr->inf.time=ff.ff_ftime;

pntr->next=NULL;

p=pntr;

a=findnext(&ff);

}

/* сортировка односвязанного списка по дате создания файлов */

p=Dir;

while(!p=NULL)

{ pntr=p;

min=p;

while(pntr!=NULL)

{ if (pntr->inf.data,min->inf.data) min=pntr;

pntr=pntr->next;

}

dir=min->inf;

min->inf=p->inf;

p->inf=dir;

p=p->next;

}

/* печать односвязанного списка с информацией о файлах */

clrscr();

printf(“ имя файла размер дата\n\n”);

while(Dir!=NULL)

{ printf(“ %-|5s %|d %d\n”, Dir->inf.name,

Dir->inf.size,

((Dir->inf.data&0177000)>>9)+1980);

p=Dir;

Dir=Dir->next;

Delete p;

}

}

Пояснение к программе

Вся информация о найденных файлах заносится в односвязанный список, который в последствии сортируется и выводится на экран.

Структура DIR содержит описание информации о файлах.

Структура List – это описание элемента однсвязанного списка.

Переменные pntr и p – это рабочие переменные, типа указатель на элемент списка.

Переменная min – это адрес элемента с информацией о файле с самой ранней датой создания файла.

Переменная dir – это переменная типа структуры DIR. Через эту переменную происходит обмен информацией.

Сотрировка односвязанного списка происходит следующим образом. Просматриваем элементы списка от начала до конца. Весь список будет разделен на две части: отсортированную и неотсортированную. Определяем адрес элемента с ранней датой создания (min), как первый элемент в неотсортированной части. Указатель p – это адрес первого несортированного элемента списка. В неотсортированной части ищем элементс ранней датой создания файла (внутренний цикл) и информацию найденного элемента записываем по адресу переменной p, а информацию по адресу p записываем на место найденного элемента min (обмен через переменную dir).

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

Пример 2.

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

Текст программы

#include <dir.h>

#include <dos.h>

#include <conio.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

void main (int argc, char argv[])

{

struct DIR {

char name[13]; //имя файла

long size; //размер

int data; // дата создания

int time; //время создания

};

struct list{

DIR inf; // информация о файле

list *next; // адрес следующей информации

};

/* описание переменных */

list *Dir=NULL, *pntr, *p, *min;

DIR dir;

Int god=2001;

Ffblk ff;

Char path[]=”c:\\dos\\*.*”;

/* формирование года */

if (argc>1) god=atoi((argv[1]);

god = 1980;

/* поиск файлов с формированием односвязанного списка */

int a=findfirst(path, &ff, FA_DIRECT && FA_ARCH);

while(!a)

{ int year=((ff.ff_fdate & 0177000)>>9);

if (year = = god)

{ pntr= new list;

if (Dir == NULL) Dir =pntr;

else p->next=pntr;

strcpy(pntr->inf.name, ff.ff_name);

pntr->inf.size=ff.ff_fsize;

pntr->inf.data=ff.ff_fdata;

pntr->inf.time=ff.ff_ftime;

pntr->next=NULL;

p=pntr;

}

a=findnext(&ff);

}

/* сортировка односвязанного списка в алфавитном порядке имен */

p=Dir;

while(!p=NULL)

{ pntr=p;

min=p;

while(pntr!=NULL)

{ if (strcmp(pntr->inf.name,min->inf.name)<0) min=pntr;

pntr=pntr->next;

}

dir=min->inf;

min->inf=p->inf;

p->inf=dir;

p=p->next;

}

}

/* вывод односвязанного списка с информацией о файлах */

clrscr();

while(Dir!=NULL)

{ printf(“ %-|5s %|d %d %d %d\n”, Dir->inf.name,

Dir->inf.size,

Dir->inf.data & 037;

(Dir->inf data & 0740)>>5;

((Dir->inf.data&0177000)>>9)+1980);

p=Dir;

Dir=Dir->next;

Delete p;

}

}

Соседние файлы в папке C_files