27



Иванова Г.С., Ничушкина Т.Н.

Конспект лекций

по курсу "Алгоритмические языки и программирование".

Тема " Файловая система Borland Pascal ".

  1. Файловая система MS DOS (организация хранения информации на внешних носителях).

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

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

Файл может хранить текст, программу, числовые данные, графическое изображение и т.д. Длина файлов измеряется в байтах, что эквивалентно емкости памяти , в котором можно хранить один символ. Максимальный размер фала ограничивается лишь техническими возможностями вычислительной системы.

При работе в среде MS DOS имена файлов подчиняются определенным правилам:

  • имя должно содержать не менее одного и не более восьми символов;

  • Файл может иметь расширение, которое отделяется от имени точкой и содержит не более трех символов;

  • для записи имен и расширений могут использоваться буквы латинского алфавита A-Z, арабские цифры и некоторые специальные символы;

  • в качестве имен запрещается использовать некоторые буквенные сочетания, которые зарезервированы операционной системой для обозначения таких устройств как принтер, дисплей и т.д. (например PRN, CON, NUL, COM1, COM2, AUX, LPT1, LPT2, LPT3)

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

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

Существуют стандартные расширения, используемые операционной системой (трансляторами и обработчиками команд). Например:

COM, EXE - исполнительные файлы (загрузочные файлы программ и команд)

FOR, PAS,BAS - файлы исходных текстов программ на алгоритмических языках

ФОРТРАН, ПАСКАЛЬ, БЭЙСИК соответственно.

Типовые расширения очень удобны, так как позволяют некоторые стандартные действия по отношению к этим файлам. Например, при расширениях COM и EXE можно обращаться к файлам только по именам, а расширение PAS позволяет работать в среде Турбо-Паскаль и т.д.

Для удобства работы с группами файлов применяются групповые имена файлов с использованием символов «*» и «?», где

  • * - любая последовательность символов;

  • ? - один любой символ.

Например:

*. EXE - все файлы с расширением EXE;

А*. COM - все файлы типа COM, имена которых начинаются на А;

??В. PAS - все файлы типа PAS, имена которых содержат три символа, последний из которых «В»;

PRG1.* - файлы любых типов с именем PRG1;

*.* - все файлы диска.

Эти групповые имена позволяют легко работать с некоторыми командами и средами.

Для размещения на диске кроме идентификации файл должен иметь место для размещения и адрес его расположения. Для этого система с помощью специальной таблицы определяет наличие свободного места на диске и его адрес и размещает там данные файла. Однако, для этого диск или дискета должны быть специальным образом размечены. Разметка осуществляется с помощью специальной системной команды инициализации. Если инициализируется диск бывший в употреблении, то вся хранившаяся на нем информация уничтожается и восстановлению не подлежит.

Как правило, диски хранят большое количество файлов (количество их на жестких дисках исчисляется сотнями и даже тысячами).Для удобства и ускорения работы с таким количеством файлов применяется древовидная структура каталогов, аналогичная библиотечной.

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

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

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

Более сложная - это древовидная система подкаталогов, пример которой представлен на рис 1.

Рис.1. Дерево каталогов пользователя.

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

Перечисляемые в маршруте каталоги разделяются символом «\», а так как корневой каталог не имеет имени, перечень начинается с символа «\».Например:

\kat1\kat2\kat3\file1.dat

При ссылке на файл, маршрут включается в спецификацию файла, следующего сразу за идентификатором дискового накопителя. Например:

c:\kat1\kat2\kat3\file1.dat

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

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

CD\mycatalog;

Для автоматического поиска файлов, в командном файле AUTOEXEC.BAT следует указать команду системы path, с помощью которой установить маршруты возможного размещения часто используемых файлов. Например:

PATH C:\mykat1;C:\mykat2;

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

  1. Файловая система Borland Pascal .

    1. Общие сведения.

В языке Турбо-Паскаль файл определяется как последовательность компонент, относящихся к одному типу: файл записей, файл целых чисел и т. п. В любой момент доступна только одна компонента. Число компонент заранее не указывается.

Файл может быть дисковым. В этом случае он представляет собой поименованную область внешней памяти на магнитном диске. Файл также может быть логическим устройством (источник или приемник информации). Логические устройства в системе имеют стандартные имена, например:

CON - при выводе относится к экрану, при вводе - к клавиатуре;

PRN - предназначено для вывода на принтер;

NUL - используется для обозначения «пустого устройства.».

Доступ к компоненте файла осуществляется с помощью указателя файла. При выполнении операции чтения или записи указатель перемещается на следующую запись ( рис.2).

Рис. 2. Перемещение указателя файла по компонентам.

Для идентификации файлов в Турбо- Паскале файловые переменные, Описываемые в программе. Синтаксическая диаграмма переменной типа файл представлена на рисунке 3




Рис. 3. Синтаксическая диаграмма файловой переменной.

Выделяют три вида файлов:

1.Типизированные

TYPE <имя> = FILE of <тип>;

где тип - любой тип переменной, принятой в Паскале, кроме FILE.

2.Текстовые

TYPE <имя> = TEXT;

3.Нетипизированные

TYPE <имя> = FILE;

применяется для скоростного обмена между внешней и оперативной памятью физическими записями указанной длины без преобразования, по умолчанию длина записи 128 байт.

Как и любая переменная языка Паскаль, файловая переменная может быть определена в разделе описания переменных

VAR F1:file of real;

F2:file;

F3: TEXT;

Кроме того, тип файловой переменной можно предварительно определить в разделе описания типов, а затем определить переменную этого типа в разделе описания переменных:

TYPE FF = file of integer;

VAR F1:FF;

Типовая последовательность действий, связанная с обработкой файлов, включает следующие этапы:

  • открытие файла;

  • выполнение операций ввода-вывода;

  • закрытие файла (при повторном открытии файл закрывается автоматически).

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

Любой программе доступны два предварительно объявленных файла со стандартными файловыми переменными:

INPUT - чтение с клавиатуры;

OUTPUT - вывод на экран.

Они доступны в любой момент и могут в макрокомандах не указываются.

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

ASSIGN (<файловая переменная>,<имя файла или логического устройства>).

Пример 2-1. Связывание файловой переменной с конкретным файлом.

PROGRAM F1;

TYPE FI1 = FILE of integer;

VAR FF: FI1, FF2, FF3:FI1

begin

ASSIGN (FF, ‘ F1.dat ‘ );

ASSIGN (FF2, ‘ LST ‘ );

ASSIGN(FF3, ‘ ‘ );

end.

    1. Стандартные процедуры и функции для работы с файлами.

Инициализация файлов.

Инициализация файла предполагает указание направления передачи данных.

В TURBO-PASKALE можно открыть файл на чтение, запись и чтение запись одновременно.

Инициализация для чтения (Установка файла на чтение).

Осуществляется с помощью процедуры

RESET(<файловая переменная.>);

В этом случае указатель файла устанавливается на компонент файла (при инициализации логического устройства оно готовится к чтению).

Если пытаться читать из несуществующего файла, то регистрируется ошибка выполнения, а функция IORESULT типа WORD получит значение отличное от 0.

  • Пример 2-2. Проверка наличия файла на диске.

VAR f: file of char;

begin

ASSIGN( f, ‘a. dat ‘ );

{$ I-} отмена контроля ошибок ввода вывода.

RESET (f);

{$ I+}- включение контроля ошибок;

if IORESULT <>0 then writeln (‘ файл не существует’);

else writeln(‘ файл существует ’);

end (в файл, открытый для чтения можно писать (обновлять) ).

Инициализация для записи (Установка файла на запись).

Обеспечивается процедурой

REWRITE(<файловая переменная>);

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

Закрытие файла.

Закрытие файла, открытого для записи или чтения можно закрыть процедурой

CLOSE(<файловая переменная >);

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

Переименование файла.

Любой существующий файл можно переименовать, используя процедуру

RENAME(<файловая переменная >,<новое имя >);

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

Удаление файла.

Уже созданный или находящийся в процессе формирования файл может быть уничтожен с помощью процедуры

ERASE(<файловая переменная >);

Перед уничтожением файл должен быть закрыт, так как удаляются только закрытые файлы.

Определение конца файла.

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

EOF(<файловая переменная >);

Функция принимает значение TRUE если указатель стоит на конце файла (после последней записи). При этом, если ведется чтение то такое значение функции означает, что файл исчерпан, а если идет запись, то она происходит в конец файла. Функция принимает значение FALSE, если конец файла при проверке еще не достигнут.

Получение информации об операции ввода-вывода

Система ввода-вывода регистрирует правильность выполнения ошибок операций работы с файлами. Эта информация может быть получена и обработана пользователем в режиме компилятора {$I-} (отключение контроля ввода-вывода) с помощью функции

IORESULT.

В качестве своего результата функция возвращает значение типа word, содержащее 0, если операция была успешной, и равная коду ошибки, если таковая произошла (приложение 1).

Процедуры работы с каталогами.

В соответствии с файловой системой, имя каталога входит в идентификацию файла, поэтому Турбо-Паскаль имеет средства для создания, уничтожения и других действий с каталогами.

  1. CHDIR(<путь>) - процедура изменения текущего каталога. Устанавливает каталог, указанный параметром «путь».

  2. GETDIR(<устройство>,<каталог>) - процедура позволяет определить имя текущего каталога на указанном устройстве.

<устройство> - 0- устройство по умолчанию;

1 - диск А;

2 - диск В.

<каталог> - переменная типа string, которая передает путь к текущему каталогу.

  1. MKDIR(<каталог>) - процедура создает новый каталог, где «каталог» содержит путь и новое имя.

  2. RMDIR(<каталог>) - процедура удаляет каталог с указанным именем. Каталог должен быть пустым.

  • Пример 2-3. Использование стандартных процедур при создании резервной копии.

program copir;

var fi,fo:text;{ файл ТИПА text }

k,i:word;

name, ; { имя файла для которого создается копия }

name_bak,s: string; ; { имя для копии файла }

const bak='.bak';

begin

writeln(' введите имя файла для редактирования');

readln(name);

k:=pos('.',name); { длина имени с точкой - <имя>.}

if k=0 then k:=length(name)+1; { длина имени без расширения - <имя> + ' '}

{формируем новое имя <имя>.BAK ,убрав точку или пробел}

name_bak:=copy(name,1,k-1)+bak;

assign(fi,name);

{$I-} reset(fi);{$I+} { проверка наличия файла с именем name}

if ioresult <> 0 then begin

writeln(#7,' нет файла с именем ',name);halt;

end;

close(fi);

assign(fo,name_bak); { проверка наличия файла с именем name_bak}

{$I-} reset(fo);{$I+}

if ioresult = 0 then begin

writeln(#7,' файл с именем ',name_bak,' есть ');

close(fo); { удаление файла с именем name_bak}

erase(fo) end;

rename(fi,name_bak); { создание резервной копии}

reset(fi);

assign(fo,name);

rewrite(fo);

while not eof(fi) do { пока не конец файла}

begin

readln(fi,s);

writeln(fo,s); { в этой точке возможен вызов процедуры редактирования файла }

end;

close(fi);

close(fo)

end.

    1. Процедуры и функции из библиотеки DOS для работы с файлами

Borland Pascal предоставляет пользователю возможность воспользоваться процедурами и функциями библиотеки DOS. Для этого необходимо в начале программы подключить библиотеку с помощью директивы USES DOS, чтобы сделать доступными ее компоненты, представленные в этом разделе.

  1. Функция DISKFREE(<диск>); определяет и возвращает объем свободного места на указанном диске в байтах . Тип результата LONGINT.

Параметр функции <диск> может принимать значение:

0 - устройство по умолчанию:

1 - диск А:

2 - диск В:

-1 - не существующий диск.

  1. Функция DISKSIZE(<диск >): возвращает полный объем указанного диска в байтах. Параметр <диск > принимает такое значение, как и в предыдущей функции.

  2. Процедура GETTIME(<файловая переменная>,<время>); возвращает время создания или последнего обновления файла

<время> - переменная типа LONGINT, в которой возвращается время в упакованном формате для файла, определенного в параметре <файловая переменная>.

  1. Процедура UNPACKTIME(<время>,<дата>); позволяет распаковать параметр <время>, представленный в виде целого числа LONGINT, в тип DATATAPE, который описан в модуле следующим образом:

Type DATATAPE = record

year : word; {19xx}

month: word; {1..12}

day: word; {1..31}

hair: word; {0..23}

min: word; {0..59}

sec: word; {0..59}

end;

Этот формат представляет время в привычном для пользователя виде.

  1. Процедура SETFTIME(<файловая переменная>,<время>) используется для установки новой даты создания или обновления файла, описываемого файловой переменной.

  2. <время> время и дата для установки в упакованном формате, представленные в виде целого числа LONGINT.

  3. Процедура PACKTIME(<дата>,<время>) позволяет упаковать параметр <дата>, представленный в виде, привычном для пользователя, и описанный с помощью переменной типа DATATAPE в целое число LONGINT, присваиваемое параметру <время>.

  4. Процедура GETFATTR(<файловая переменная>,<атрибуты>) применяется для получения атрибутов файла, указанного файловой переменной.

<атрибуты> переменная типа WORD, в младшем байте которого возвращаются атрибуты файла. Для расшифровки байта атрибутов в модуле описана константа следующего содержания:

Const Readonly = $01; только чтение

Hidden = $02; скрытый файл

Sysfile = $04; системный файл

VolumeID =$08; идентификатор тома

Duirectory = $10; имя подкаталога

Archive = $20; архивный файл

Anyfile = $3F; любой файл

Комбинация битов в байте может указывать самые разные варианты.

Процедура SETFATTR(<файловая переменная>,<атрибуты>) служит для установки атрибутов файла указанного файловой переменной.

<атрибуты> переменная типа WORD, в младшем байте которого передаются процедуре атрибуты файла.

  1. Функция FSEARCH(<имя>,<список каталогов>) Ищет файл в списке каталогов.

<имя> - имя отыскиваемого файла ( строковое выражение типа PATCHSTR=STRING[79] ; имени может предшествовать путь).

<список каталогов> - список каталогов, в которых ищется файл ( строковая переменная типа STRING ) ; имена каталогов разделяются запятой.

Результат поиска возвращается в виде строки типа PATCHSTR=STRING[79]. В строке содержится путь и имя файла, если поиск был успешным. В противном случае возвращается пустая строка.

  1. Функция FSPLIT(<файл>,<путь >,<имя>,<расширение>) применяется для расщепления имени файла, т. е. Возвращает в качестве отдельных параметров путь к файлу, его имя и расширение;

<файл> - строковое выражение, содержащее спецификацию файла

<путь> - переменная типа PATCHSTR=STRING[67], в котором возвращается путь к файлу;

<имя> - переменная типа PATCHSTR=STRING[8], в котором возвращается имя файла;

<расширение> - переменная типа PATCHSTR=STRING[4], в котором возвращается расширение с предшествующей ему точкой;

Процедура не проверяет наличие на диске указанного файла. В качестве входного параметра может использоваться переменная типа PATCHSTR=STRING[79].

  1. Функция FEXPAND(<файл>) применяется для дополнения файлового имени до полной спецификации (с указанием устройства и пути);

<файл> - строковое выражение или переменная типа PATCHSTR.

Функция не проверяет наличие файла на диске, а просто дополняет имя файла недостающими параметрами. Результат возвращается в строке типа PATCHSTR=STRING[79].

  • Пример 2-4. Использование процедур и функций DOS.

program fundos; { проверка функций библиотеки dos}

uses dos,crt;

const name:string='c:\tanya\pasc\filezap\pr.rez';

var fi,fo:text;{ файл ТИПА text }

k,i:word;time,size:longint; {переменные для хранения времени и размеров}

date:datetime; {переменные для преобразования даты}

pathf:dirstr; { описываются как стандартные типа модуля dos }

namef:namestr;

extf:extstr;

atr:byte; {переменные для хранения байта атрибутов файла}

begin

clrscr;

writeln(' введите имя файла для работы ');

readln(name);

assign(fi,name);

{$I-} reset(fi);{$I+} { проверка наличия файла с именем name}

if ioresult <> 0 then begin

writeln(#7,' нет файла с именем ',name);halt;

end;

getftime(fi,time); {процедура определения даты создания файла}

unpacktime(time,date); {процедура преобразования даты в понятный вид}

writeln('дата создания файла =',date.year:5,date.month:3,date.day:3);

writeln('время создания файла =',date.hour:3,date.min:3,date.sec:3);

with date do begin

year:=1998;

month:=7;

day:=31

end;

packtime(date,time); {упаковка даты для внесения изменений в тип longint }

setftime(fi,time); {установка новой даты создания или корректировки файла}

writeln(' после установки новой даты ');

writeln('дата создания файла =',date.year:5,date.month:3,date.day:3);

writeln('время создания файла =',date.hour:3,date.min:3,date.sec:3);

fsplit(name,pathf,namef,extf); {«расщепление» имени файла на составляющие}

writeln('полное имя файла =',pathf:25,namef:12,extf:8);

getfattr(fi,k); {определение атрибутов файла}

atr:=lo(k); {}

writeln(' байт атрибутов ',atr);

size:=diskfree(1);

writeln(' свободноe место на диске ',size:10,' байт ');

close(fi);

end.

Результат работы программы:

введите имя файла для работы

c:\tanya\pasc\filezap\pr.res

дата создания файла = 1998 12 11

время создания файла = 10 47 22

после установки новой даты

дата создания файла = 1998 7 31

время создания файла = 10 47 22

полное имя файла = c:\tanya\pasc\filezap\ pr .res

байт атрибутов 32

свободное место на диске 559104 байт

    1. Операции ввода - вывода Borland Pascal для работы с файлами различной внутренней структуры

      1. Типизированные файлы.

Типизированный файл - это файл, компоненты которого имеют один тип, задаваемый при объявлении файловой переменной. Компоненты файла хранятся на диске во внутреннем формате, в соответствии с типом, определенном при описании файла. Поэтому, иногда типизированные файлы называют файлами без преобразования. Определить файл можно двумя способами:

1. предварительно ввести новый тип - файл переменных определенного типа, а затем определить файловую переменную этого типа, например

TYPE <имя типа> = FILE of <тип>

VAR <файловая переменная >: <имя типа>;

2. сразу определить файловую переменную как файл определенного типа, например

VAR <файловая переменная >: FILE of <тип>

Компоненты типизированного файла могут быть любого типа, кроме файлового. Поскольку длина каждой компоненты файла строго постоянна, возможен прямой доступ к каждой компоненте.

Типизированный файл открывается одновременно на запись и на чтение процедурами REWRITE или RESET. Однако есть различие в применении этих процедур. При использовании процедуры REWRITE, открывается новый файл и если файл с таким именем уже есть, он уничтожается. Применение процедуры RESET вызывает открытие уже существующего файла. Его отсутствие на диске вызывает ошибку ввода-вывода. После открытия файла, указатель обоих случаях устанавливается в начало.

Следовательно, перед первым обращением к процедурам ввода-вывода указатель файла стоит в его начале и указывает на первую компоненту с номером 0. После каждого чтения или записи указатель сдвигается к следующей компоненте файла. Такой способ доступа к файлу называется последовательным. Однако, есть процедуры, обеспечивающие реализацию прямого доступа к компонентам файла.

Процедуры и функции работы с типизированными файлами.

  1. Процедура READ(<файловая переменная>,<список ввода>) предназначена для чтения очередных компонент типизированного файла.

<список ввода> список, содержащий одну или несколько переменных такого же типа, что и компоненты файла, разделенных запятыми.

Если файл исчерпан, обращение к процедуре вызывает ошибку ввода-вывода.

  1. Процедура WRITE(<файловая переменная>,<список ввода>) служит для записи данных в типизированный файл.

<список ввода> список, содержащий одно или более выражений такого же типа, что и компоненты файла, разделенных запятыми.

  1. Процедура SEEK(<файловая переменная>,<номер компоненты>) предназначена для реализации прямого доступа к типизированному файлу, обеспечивая установку указателя на требуемую компоненту файла.

Местоположение компоненты определяется ее смещением относительно начала файла. Это смещение определяется как число компонент, которое надо пропустить, чтобы встать на нужную. Так, у первой компоненты смещение 0, у второй 1 и т.д., поэтому:

<номер компоненты> переменная типа longint, указывающая смещение компоненты от начала файла и совпадающая с номером компоненты, если отсчет компонент вести с 0..

  1. Функция FILESIZE(<файловая переменная>) служит для определения размера файла, указанного файловой переменной. Функция возвращает значение типа longint, которое содержит количество компонент файла. Отсчет компонент файла ведется с 1.

Может использоваться для установки на конец файла совместно с SEEK():

SEEK(<файловая переменная>, FILESIZE(<файловая переменная>)).

  1. Функция FILEPOS(<файловая переменная>) применяется для определения текущего положения указателя файла. Функция возвращает значение типа longint, содержащее порядковый номер того компонента, который будет обрабатываться следующей операцией ввода-вывода.. Нумерация компонент в функции файла начинается с 0.

  • Пример 2-5. Определение суммы компонент файла, стоящих на четных местах.

{программа создает файл, содержащий случайное количество случайных целых чисел. Затем определяется сумма чисел, стоящих на четных местах в файле. }

Program tipfile1;

uses crt;

Type t=file of integer; {вводится новый тип - файл целых чисел}

var f1:t; {файловая переменная типа файл целых чисел}

k,i,l:integer;

s:real;

Begin

clrscr;

Assign(f1,'pr.dat');{ связать файловую переменную с реальным файлом}

Rewrite(f1); { открыть файла на запись}

randomize;

k:=random(50); { случайное количество}

for i:=1 to k do begin

l:=random(21); { случайных чисел}

write(f1,l); end; {записать очередной компоненты в файл }

seek(f1,0); {установка указателя на начало файла}

writeln(' исходный файл ');

i:=0;

while not eof(f1) do {цикл пока не конец файла - обработка}

begin

read(f1,l);

i:=i+1;

if (i mod 5)=0 then writeln(l:4)

else write(l:4);

end;

writeln;

writeln('**********************************');

writeln(' искомые числа файла ');

seek(f1,0); {установка указателя на начало файла}

i:=1;s:=0;k:=0;

while(not eof(f1)) and (i<=filesize(f1)-1) do

begin{ пока не конец файла или пока i не больше номера последней комп.}

seek(f1,i);

read(f1,l);

s:=s+l;

i:=i+2;

k:=k+1;

if (k mod 5)=0 then writeln(l:4)

else write(l:4);

end;

writeln;

writeln('**********************************');

writeln(' сумма чисел,стоящих на четных местах в файле равна ',s:8:2);

close(f1); { закрыть файл}

End.

Результат работы программы

исходный файл

6 8 13 5 18

8 9 11 4 5

5 12 3 18 3

11 13 7 3 1

3 9 7 18

**********************************

искомые числа файла

8 5 8 11 5

12 18 11 7 1

9 18

**********************************

сумма чисел, стоящих на четных местах в файле равна 113.00

  • Пример 2-6. Определение среднего арифметического положительных компонент типизированного файла.

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

Program Fileintegeк;

Uses CRT;

Type

t=file of integer; {новый тип - файл целых чисел}

var

f:t; { переменная типа файл целых чисел}

filename:string[6]; {переменная для имени файла}

kol,i,n,a:integer; sar:real;

Function Sr(var f1:t;var k:integer):real;

{ функция вычисляет и возвращает среднее значение положительных компонент файла; входной параметр - файловая переменная выходной параметр к - количество положительных компонент }

var

s:real; n1:integer;

begin

s:=0;

k:=0;

Reset(f1); {открыть файл на чтение}

writeln(' содержимое файла ');

while not Eof(f1) do { цикл пока не конец файла}

begin

read(f1,n1); { читать компонент }

write(n1:4); {вывести на печать компонент}

if n1>0 then

begin

s:=s+n1;

k:=k+1;

end;

Sr:=s/k;

end;

writeln;

close(f1); { закрыть файл}

end;

Begin { Основная программа}

clrscr;

writeln('введите имя файла');

readln(filename);

Assign(f,filename); {установить связь с файлом на диске}

Rewrite(f); {открыть файл на запись}

writeln(' введите число компонентов файла ');

readln(n);

for i:=1 to n do

begin

read(a); {читать с клавиатуры}

write(f,a); {писать в фал }

end;

Close(f); {закрыть файл}

sar:=sr(f,kol);

writeln('среднее арифм. положительных компонент файла=',sar:5:3);

writeln('корличество положительных компонент файла=',kol:5)

End.

Результат работы программы:

введите имя файла

yyy.dat

введите число компонент файла

10

23 -45 8 0 5 0 -6 12 35 0

содержимое файла:

23 -45 8 0 5 0 -6 12 35 0

среднее арифм. положительных компонент файла=16.600

количество положительных компонент файла= 5

  • Пример 2-7. Применение типизированного файла для создания систем учета товаров на складе.

{Программа вводит данные о товаре с пульта и выводит эти данные в файл записей. Затем проверяется информации путем поиска в файле и подсчета стоимости товара на складе}

program ex;

uses crt;

type st=string[10];

tovar=record

nazv:st;

kol:word;

cena:word;

end;

var tv:tovar; {переменная типа tovar}

fname:string; {переменная для задания имени файла}

f1:file of tovar; {файлвая переменная - файл типа запись}

max,sum:longint;

n,i:integer;

nazm:st;

begin clrscr;

writeln('введите имя файла ');

readln(fname);

assign(f1,fname); {связывание файловой переменной с файлом на диске}

{$I-}reset(f1);{$I+} {открытие на чтение файла }

if ioresult <> 0 then

begin {если файла с таким именем нет открытие на запись}

rewrite(f1); { и ввод информации о товарах}

writeln('Введите данные о количестве товара ');

readln(n);

for i:=1 to n do

begin

with tv do begin

write(' название ',i:3, '-го товара ');readln(nazv);

writeln(' количество цена');readln(kol,cena);

end;

write(f1,tv); { запись данных о товаре в файл на диск}

end;

end;

writeln('Название товара количество цена');

seek(f1,0); { установка указателя файла на начало}

sum:=0;max:=-200;nazm:='';

while not eof(f1) do

begin

read(f1,tv); {чтение записей из файла для анализа }

writeln(tv.nazv:10,' ',tv.kol:10,' ',tv.cena:9);

sum:=sum+tv.cena*tv.kol;

if tv.kol >=max then

begin

max:=tv.kol;nazm:=tv.nazv

end;

end;

writeln;

writeln('общая цена товара на складе равна ');

writeln(sum,' условных единиц ');

writeln(' наибольшее количество товара ',max:6,' с названием ',nazm);

readln;

close(f1);

end.

Результат работы программы

введите имя файла

tt.dat

Название товара количество цена

сумки 100 300

портфели 1000 200

кошельки 2000 58

бумажники 1200 60

папки 3000 45

общая цена товара на складе равна

94248 условных единиц

наибольшее количество товара 3000 с названием папки

Как и любая переменная, файл может быть передан в качестве параметра в процедуру или функцию. В этом случае необходимо использовать передачу параметра адресом ( параметр - переменная), так как создать копию файла внутри подпрограммы невозможно. Кроме того, чтобы можно было передать файл в качестве параметра, как и в случае сложных структур данных, для него необходимо предварительно описать файловый тип в разделе описания типов type.

  • Пример 2-8. Использование файловой переменной в качестве параметра.

{Программа создает файл целых чисел и печатает его содержимое. Затем файл модифицируется путем добавления в нее новых значений и снова печатает его содержимое. Для печати используется процедура печати с одним параметром -файловой переменной}

type ff=file of integer; {новый тип - файл целых чисел}

var

f1:ff; {файловая переменная типа файл целых чисел}

a,i:integer;

fname:string[10];

Procedure Prfile(var f:ff);

{процедура печати содержимого файла целых чисел

получает в качестве параметра файл целых чисел}

begin

reset(f);

writeln('содержимое файла');

i:=1;

while not eof(f) do

begin

read(f,i);

write(i:4);

end;

close(f);

writeln;

end;

Begin

writeln('введите имя файла');

readln(fname);

Assign(f1,fname);

writeln('введите ',5:3,' целых чисел:');

rewrite(f1);

for i:=1 to 5 do

begin

read(a);

write(f1,a);

end;

close(f1);

write(' начальное ');

Prfile(f1); {вызвать процедуру печати для файла f1}

reset(f1); {открыть файл для чтения}

seek(f1,filesize(f1)); {установка указателя в конец файла для дозаписи}

for i:=6 to 10 do write(f1,i); {добавление записей в файл}

close(f1); {закрытие файла после дозаписи}

Write(' после дозаписи ');

prfile(f1); {вызов процедуры печати модифицированного файла}

end.

Результат работы программы:

yyyy.dat

введите 5 целых чисел:

34 5 67 9 12

начальное содержимое файла

34 5 67 9 12

после дозаписи содержимое файла

34 5 67 9 12 6 7 8 9 10

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

  • Пример 2-9. Вычеркивание из типизированного файла записей.

{ Программа создает процедуру выделения из текстового файла информации о студентах в файл типа " запись" и процедуру удаления из файла записи с ошибочной группой. В основной программе вызываются соответствующие процедуры и печатаются содержимое файлов до и после обработки}

program vichzap;

uses crt;

type ss=string;

type zap=record

fam:string[10];

gr:integer;

oc1,oc2:byte;

adr:string[20];

end;

type pr=file of zap;

var

f:text; { текстовый файл исходных данных см. раздел 2.4.2}

fz,fr:pr; {файлы типа запись}

i,j:integer;

p:zap;

procedure vid(var f:text;var fz:pr);

{ процедура формирования типизированного файла записей о студентах

из текстового файла с исходными данными}

var z:zap;

begin

rewrite(fz); {открыть файл типа запись на запись}

reset(f); {открыть текстовый файл на чтение}

while not eof(f) do {пока не конец входного файла}

begin

readln(f,z.fam,z.gr,z.oc1,z.oc2,z.adr); {читать из входного файла}

write(fz,z); { писать в файл типа запись}

end;

reset(fz); {установить файл на начало}

end;

procedure vich(var f:pr);

{ процедура удаления из файла некоторых записей }

var z:zap;

f1:pr;

begin

assign(f1,'fr.dat');

reset(f); {открыть файл на чтение}

rewrite(f1); {открыть временный файл на запись}

while not eof(f) do {пока не конец файла}

begin

read(f,z); {читать из основного файла }

if z.gr<>1 then {если номер группы не равен 1}

write(f1,z); {писать во временный}

end;

close(f); {закрыть основной файл}

close(f1); {закрыть временный файл}

erase(f); {удаление основного файла}

rename(f1,'fz.dat'); {переименование временного файла}

assign(f,'fz.dat'); {переназначить временный файл, как основной}

reset(f) {открыть основной файл на чтение}

end;

{ основная программа}

begin

clrscr;

assign(f,'f.dat'); {назначить файл для входных данных }

assign(fz,'fz.dat'); { назначить файл для хранения записей о студентах}

vid(f,fz); {вызвать процедуру формирования файла записей}

writeln(' данные, считанные из файла входного файла'); writeln;

while not eof(fz) do { пока не конец файла записей}

begin

read(fz,p); {читать запись из файла}

writeln(p.fam:10,p.gr:3,p.oc1:3,p.oc2:3,p.adr); {печатать запись}

end;

writeln;

writeln(' результат вычеркивания ');

writeln;

vich(fz); { вызвать процедуру вычеркивания из файла записей}

while not eof(fz)do { пока не конец файла}

begin

read(fz,p); { читать запись}

writeln(p.fam:10,p.gr:3,p.oc1:3,p.oc2:3,p.adr); { печатать запись}

end;

close(fz); { закрыть файл записей}

close(f); { закрыть файл исходных данных}

end.

Результат работы программы

данные, считанные из файла входного файла

иванов 12 5 4 молодежная д.5 кв.3

петров 12 4 4 юбилейный д.45 кв.4

сидоров 1 3 4 калинина д.85 кв.33

васин 12 5 4 комсомольскаяя д.32

мамин 1 5 5 молодежная д.1 кв.6

рязанов 12 5 3 молодежная д.6 кв.2

результат вычеркивания

иванов 12 5 4 молодежная д.5 кв.3

петров 12 4 4 юбилейный д.45 кв.4

васин 12 5 4 комсомольскаяя д.32

рязанов 12 5 3 молодежная д.6 кв.2

      1. Текстовые файлы.

Текстовый файл - это файл, элементами которого являются символьные строки переменной длины, заканчивающиеся признаками конца строки ( EOLN ). В конце всего файла - признак конца файла (EOF). Эти признаки можно протестировать одноименными логическими функциями, но можно воспользоваться следующими системными соглашениями:

EOLN - это последовательность кодов ASCII 13 (CR - конец строки, вводится при нажатии клавиши «ENTER») и 10 (LF - перевод каретки)

EOF - это код ASCII 26 (CTRL - Z))

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

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

1. предварительно ввести новый тип - файл переменных типа TEXT, а затем определить файловую переменную этого типа, например

TYPE <имя типа> = TEXT;

VAR <файловая переменная >: <имя типа>;

2. сразу определить файловую переменную как файл типа TEXT, например

VAR <файловая переменная >: TEXT;

Текстовый файл можно открыть на запись, чтение и добавление. Файл, открытый на запись не может использоваться для чтения и наоборот. При открытии файла на добавление, система проверяет не был ли файл открыт на чтение или запись, и если такой факт имел место - производится сначала его открытие, а затем уже открытие на добавление.

Процедура работы с текстовыми файлами.

  1. Функция EOLN(<файловая переменная>) - логического типа, возвращает TRUE, если во входном текстовом файле достигнут маркер конца строки; при отсутствии файловой переменной проверяется стандартный файл INPUT;

Имеется ряд отличий в работе функций EOLN и EOF с дисковыми файлами и логическими устройствами. Для логического устройства невозможно предвидеть, каким будет результат чтения очередного символа. Поэтому при работе с логическим устройством функция EOLN возвращает TRUE, если последним считанным символом был CR CTRL-L. при работе с диском функция EOLN возвращает TRUE, если последним считанным символом будет CR CTRL-L

Аналогичное различие наблюдается и в функции EOF: для логического устройства TRUE возвращается в случае, если последним символом был CTRL-L, а при чтении с диска - если следующим считываемым символом будет CTRL-L.

  1. Процедура READ(<файловая переменная>,<список ввода>) обеспечивает ввод символов, строк и чисел.

<список ввода> - последовательность из одной или более переменных типа CHAR, STRING, а также любого целого и вещественного типа. При обработке переменных типа CHAR выполняется чтение одного символа из файла и присваивание считанного значения переменной. Если перед выполнением чтения указатель файла достиг конца очередной строки, то результатом чтения будет символ CR (ASCII код 13 ), а если достигнут конец файла, то символ EOF ( ASCII код 26 ).

При вводе переменных типа STRING количество считанных процедурой и перемещенных в строку символов равно максимальной длине строки, если раньше не встретились символы CR или EOF, которые в строку не переносятся. Символы, выходящие за размер максимальной длины строки - отбрасываются. Новое обращение к процедуре READ вернет пустую строку. Следовательно, READ не в состоянии читать последовательность строк, так как первая строка будет прочитана правильно, а все последующие окажутся пустыми.

При вводе числовых данных READ пропускает все пробелы, знаки табуляции и маркеры до первого до первого значащего символа и читает строку до пробела, знака табуляции и маркера. Полученная подстрока преобразуется из символьного вида во внутреннее представление в соответствии с типом числа и присваивается переменной из списка. Если нарушен формат - возникает ошибка ввода-вывода. если прочитан конец файла - переменной присваивается 0.


Случайные файлы

Файл
2157.rtf
182979.rtf
19677-1.rtf
97284.rtf
1170-1.rtf