Информатика_ч2-записи
.pdf11
текущего компонента в переменную Z, указатель файла устанавливается на следующий компонент (запись).
Write (F, Z) - записать новый компонент в файл. Переменные Zl, Z2, ... , ZN записываются в дисковый файл, определенный переменной F. После выполнения процедуры указатель перемещается к следующему компоненту.
Seek (F, k) - установить указатель на компонент Zk с порядковым номером k в файле. Указатель перемещается к компоненту с номером k, начиная счет с нуля, т. е. первый компонент имеет номер 0, второй - 1, третий - 2 и т. д.
Close(F) - закрыть файл. Выполнение процедуры обеспечивает закрытие файла, назначенного переменной F. Если файл был открыт, никогда не следует выходить из программы, предварительно не закрыв его.
Erase(F) - уничтожить файл. Выполнение процедуры вызывает уничтожение файла, назначенного переменной F. Если производится уничтожение открытого файла, его необходимо предварительно закрыть с помощью процедуры Close.
Rename(F, ST) - переименовать файл. Выполнение процедуры вызывает занесение в каталог диска (директорий) нового имени файла, определенного переменной F. Новое имя определяется значением текста в строке ST.
Truncate (F) - уничтожить все компоненты файла, начиная с места текущего положения указателя, и подготовить файл для записи.
Помимо перечисленных выше процедур следует использовать перечисленные ниже функции, которые выполняют дополнительные действия, облегчающие программисту обслуживание уже существующих файлов.
Eof (F) - проверить маркер "конец файла". Значение функции равно True, если указатель файла находится сразу за последним компонентом файла, и False в любом другом случае.
FilePos (F) - определить текущий номер компонента. Функция возвращает целочисленное значение, равное номеру компонента, на котором установлен в данный момент указатель файла, соответствующего переменной F. Отсчет номера компонента начинается с нуля.
FileSize (F) - определить размер файла. Функция возвращает целочисленное значение, равное количеству компонентов файла, соответствующего переменной F. Эта функция обычно используется для проверки, содержит файл какую-либо информацию или является пустым. Если FileSize (F) = 0, то файл пуст, в другом случае файл содержит данные.
lOResult (F) - проверить результат выполнения последней операции ввода-вывода на наличие ошибок. Если ошибка обнаружена, функция возвращает номер ошибки, если ошибок нет, возвращает значение 0. Эта функция используется при пассивном состоянии директивы {$I-} для организации обработки ошибок ввода-вывода самим пользователем. Если программа для обработки ошибок отсутствует, наличие ошибки ввода-вывода не вызывает прерывания программы и выполняется следующий оператор.
11.3. Организация последовательного доступа к компонентам файла
Режим последовательного доступа используются для решения задач, требующих поочередной обработки компонентов файла при отсутствии жестких ограничений на
12
время решения. Работа с последовательными файлами предполагает создание файла, обработку и возможно корректировку всех его компонентов.
Для создания последовательного файла необходимо выполнить следующие шаги: присвоить файлу имя (процедура Assign); открыть новый файл (процедура
Rewrite); подготовить информацию для ввода; записать в файл компоненты (оператор write); закрыть созданный файл (процедура Close).
Пример 119. Ввести с клавиатуры в соответствии с табл. 48 сведения о 20 студентах и сохранить эту информацию в файле STUDENTS.DAT в корневом каталоге диска A.
Таблица 48.
Номер |
Фамилия студента |
Дата |
Номер |
Размер |
зачетной |
|
рождения |
группы |
стипендии, |
книжки |
|
|
|
руб. |
TAB |
FIO |
DATA |
GRUP |
STEPA |
100000 |
АФАНАСЬЕВ |
01.02.83 |
ПИ-11 |
500.00 |
100001 |
СЫЧЕВ |
13.03.84 |
ПИ-11 |
500.00 |
100002 |
ВАСИЛЬЕВ |
15.01.84 |
ПИ-11 |
350.00 |
100003 |
УШАКОВ |
12.12.83 |
ПИ-11 |
0.00 |
100004 |
СИДОРОВ |
01.11.83 |
ПИ-11 |
500.00 |
100005 |
ГАВРИЛОВ |
10.12.83 |
ПИ-11 |
850.00 |
100006 |
ИВАНОВА |
15.05.84 |
ПИ-11 |
500.00 |
100007 |
ВЕЙНЕРМАН |
09.06.83 |
ПИ-11 |
500.00 |
100008 |
ЯКУШЕВ |
24.10.83 |
ПИ-11 |
0.00 |
100009 |
ЗИБЕРМАН |
13.09.84 |
ИС-11 |
0.00 |
100010 |
АНИСИМОВ |
11.04.84 |
ИС-11 |
500.00 |
100011 |
ПЕТРОВ |
03.05.84 |
ИС-11 |
350.00 |
100012 |
БУНАКОВ |
21.06.83 |
ИС-11 |
850.00 |
100013 |
ФАДЕЕВ |
04.10.83 |
ИС-11 |
350.00 |
100014 |
СЕМЕНОВ |
30.01.84 |
ИС-11 |
500.00 |
100015 |
ЩУКИНА |
15.03.84 |
ИС-11 |
0.00 |
100016 |
ВАХРУШЕВА |
13.02.84 |
ИС-11 |
350.00 |
100017 |
ВЫСОЦКИЙ |
06.08.83 |
ИС-11 |
850.00 |
100018 |
СЕРЕГИНА |
05.04.84 |
ИС-11 |
500.00 |
100019 |
ГОРОХОВ |
15.09.83 |
ИС-11 |
500.00 |
Ниже приведен код программы, выполняющий эту задачу. В качестве рабочей таблицы для промежуточного хранения информации о студентах используется массив записей MSTD. Программа работает в два в два этапа. Первый этап состоит в вводе информации о всех 20 студентах (цикл FOR). На втором этапе создается новый файл A:\STUDENTS.DAT и содержимое таблицы MSTD строка за строкой переносится в этот файл.
PROGRAM PR119;
TYPE STUDENT = RECORD
TAB: |
LONGINT; |
{НОМЕР ЗАЧЕТНОЙ КНИЖКИ} |
FIO: |
STRING[20]; |
{ФАМИЛИЯ И.О.} |
DATA: STRING[8]; |
{ДАТА РОЖДЕНИЯ} |
|
GRUP: STRING[7]; |
{НОМЕР ГРУППЫ} |
|
STEPA: REAL |
{РАЗМЕР СТИПЕНДИИ, РУБ.} |
|
END; |
|
|
13
VAR MSTD: ARRAY[0..19] OF STUDENT; I: INTEGER; FSTD: FILE OF STUDENT;
BEGIN {ИНИЦИАЛИЗАЦИЯ ТАБЛИЦЫ} WRITELN('ВВЕДИТЕ ДАННЫЕ О 20 СТУДЕНТАХ'); FOR I := 0 TO 19
DO WITH MSTD[I] {ВВОД ДАННЫХ В I-ю СТРОКУ ТАБЛИЦЫ} DO BEGIN
WRITE(I+1: 2,'. НОМЕР ЗАЧЕТНОЙ КНИЖКИ: '); READLN(TAB);
WRITE (' |
ФАМИЛИЯ И.О. |
: '); |
READLN(FIO); |
WRITE (' |
ДАТА РОЖДЕНИЯ |
: '); |
READLN(DATA); |
WRITE (' |
НОМЕР ГРУППЫ |
: '); |
READLN(GRUP); |
WRITE (' |
РАЗМЕР СТИПЕНДИИ,РУБ.: '); READLN(STEPA) |
||
END; |
|
|
|
{ЗАПИСЬ ТАБЛИЦЫ MSTD В ФАЙЛ} ASSIGN(FSTD, 'A:\STUDENTS.DAT'); REWRITE(FSTD);
FOR I := 0 TO 19
DO IF LENGTH(MSTD[I].FIO) > 0 THEN WRITE(FSTD, MSTD[I]);
CLOSE(FSTD)
END.
В результате выполнения программы в файл STUDENTS.DAT будет занесена информация из табл. 1.
Пример 120. В файле STUDENTS.DAT, расположенном в корневом каталоге диска A хранятся сведения о 20 студентах (см. табл. 1). Требуется вывести на экран монитора в алфавитном порядке фамилии студентов группы ИС-11 и номера их зачетных книжек, которые получают стипендии указанного размера.
Решение этой задачи осуществляется в три этапа. На первом этапе следует прочитать по порядку все записи из файла режиме последовательного доступа. Каждую запись проанализировать на условия отбора (то есть, отфильтровать). При выполнении условий GRUP = 'ИС-11' и STEPA = 1000 запись о студенте следует поместить в промежуточный массив записей MSTD. Подсчитать K - число записей в массиве.
На втором этапе, если K > 1, следует отсортировать записи в массиве MSTD в порядке возрастания значений поля FIO.
На последнем этапе в зависимости от значения K следует на экран монитора вывести сообщения:
при K = 0 - 'В группе ИС-11 нет студентов не получающих стипендию 1000руб.'; при K > 0 - список студентов, содержащий поля FIO (Фамилия) и TAB (Номер
зачетной книжки). PROGRAM PR120;
TYPE STUDENT = RECORD
TAB: |
LONGINT; |
{НОМЕР ЗАЧЕТНОЙ КНИЖКИ} |
FIO: |
STRING[20]; |
{ФАМИЛИЯ И.О.} |
DATA: STRING[8]; |
{ДАТА РОЖДЕНИЯ} |
|
GRUP: STRING[7]; |
{НОМЕР ГРУППЫ} |
|
14 |
STEPA: REAL |
{РАЗМЕР СТИПЕНДИИ, РУБ.} |
END; |
|
VAR STD, RAB: STUDENT; MSTD: ARRAY[0..19] OF STUDENT; FSTD: FILE OF STUDENT; SFILE, SGR: STRING;
I, J, K: LONGINT; STP: REAL; BEGIN
WRITELN('ВВЕДИТЕ ДИСК, ПУТЬ И ИМЯ ФАЙЛА'); READLN(SFILE); WRITELN('УКАЖИТЕ НОМЕР ГРУППЫ'); READLN(SGR); WRITELN('УКАЖИТЕ РАЗМЕР СТИПЕНДИИ'); READLN(STP);
{ЧТЕНИЕ ДАННЫХ ИЗ ФАЙЛА} ASSIGN(FSTD, SFILE);
RESET(FSTD); K:=0; {Число записей удовлетворяющих условиям поиска} WHILE NOT EOF(FSTD)
DO BEGIN READ(FSTD, STD);
IF (STD.GRUP = SGR) AND (STD.STEPA = STP) THEN BEGIN
MSTD[K]:=STD; {Копирование записи STD в массив MSTD} K := K + 1
END END; CLOSE(FSTD); IF K > 0 THEN BEGIN
FOR I := 1 TO K-1
DO FOR J := K-1 DOWNTO I
DO IF MSTD[J-1].FIO > MSTD[J].FIO
THEN BEGIN {Перестановка записей местами}
RAB := MSTD[J-1]; MSTD[J-1] := MSTD[J]; MSTD[J] := RAB END
END; IF K>0
THEN FOR I:= 0 TO K-1
DO WRITELN(MSTD[I].FIO: 22, MSTD[I].TAB:9, MSTD[I].STEPA: 9: 2)
ELSE WRITELN('В группе ', SGR,' нет студентов имеющих стипендию ', STP: 2: 2,
'руб.')
END.
Если задать значения SGR = 'ИС-11' и STP = 500, то результатом работы программы будет таблица представленная на рис. 35.
15
Рис. 35. Результат работы программы
11.4. Организация прямого доступа к компонентам файла
Файлы произвольного доступа создаются для решения задач, требующих оперативного доступа к хранимой информации или при наличии зависимости значения поля компонента от порядкового номера компонента в файле. Последовательный доступ в этих файлах возможен, но для большинства решаемых задач неэффективен.
Работа с файлом произвольного доступа предполагает его создание, просмотр и корректировку. Организовать файл произвольного доступа можно двумя способами:
Создать последовательный файл и обращаться к компонентам по их порядковому номеру, трактуя последовательный файл как произвольный;
Создать дополнительный, так называемый индексный файл, содержащий записи с двумя полями. Первое поле индексного файла - ключевое, второе поле номер записи в основном информационном файле.
Ключевое поле содержит упорядоченные значения реквизитов представляющих собой значения одного из полей записей основного файла. Эти значения могут быть уникальными - в этом случае говорят, что это первичный ключ и его можно использовать для идентификации объекта. В некоторых задачах значения в ключевом поле могут повторяться, в этом случае ключ не является уникальным, но помогает быстро найти все записи основного файла, имеющие указанное значение. Таким образом, поиск интересующих нас объектов начинается по значению ключа в индексном файле. Когда запись в индексном файле найдена, то во втором поле находится номер записи в основном файле. Это значение используется процедурой Seek - установка указателя файла на компонент по его номеру.
Индексные файлы нужны для ускорения процедуры поиска требуемых записей в основном файле. Записи основного файла содержат много информационных полей и считываются с диска в буфер оперативной памяти в небольшом количестве. Поэтому просмотр таких записей и поиск по значению поля занимает большое время. Индексные файлы по размеру на один или два порядка меньше, поэтому анализ и поиск номеров записей в них гораздо быстрее (в тысячи раз).
Ключевые поля индексного файла бывают простые и составные. Простой ключ представляет собой значение только одного поля основного набора, или части этого поля. Составной ключ - это комбинация двух и более полей, или их частей. Составной ключ формируется с двумя целями. Во-первых придать записи уникальный префикс, играющий роль идентификатора. Например, фамилия + имя + отчество - позволяют в достаточно
16
большом коллективе около 4000 человек, где десять Ивановых, восемь Петровых и два Гаскарова, выбрать одного единственного сотрудника. Во-вторых упорядочить все записи файла в соответствии с требованиями. Например, требуется, упорядочить всех сотрудников по фамилии, для совпадающих фамилий по инициалам.
Имя индексного файла обычно формируется следующим образом. Собственное имя, до восьми литер, часто повторяет имя основного базового файла. Напомним, что в нашем примере базовый файл имеет имя STUDENTS.DAT. Последние три символа определяют тип файла. Для индексных файлов тоже существуют свои расширения, принятые в соответствующих системах программирования баз данных. Мы будем использовать расширение .NTX, позаимствовав его у индексных файлов CLIPPER. Таким образом, полное имя нашего индексного файла будет STUDENTS.NTX.
Приведем структуру индексного файла STUDENTS.NTX и его данные, построенного для табл. 48, соответствующей файлу STUDENTS.DAT (см. табл. 49).
Таблица 49.
Фамилия студента |
Номер записи |
FIO |
NAMBER |
АНИСИМОВ |
10 |
АФАНАСЬЕВ |
0 |
БУНАКОВ |
12 |
ВАСИЛЬЕВ |
2 |
ВАХРУШЕВА |
16 |
ВЕЙНЕРМАН |
7 |
ВЫСОЦКИЙ |
17 |
ГАВРИЛОВ |
5 |
ГОРОХОВ |
19 |
ИВАНОВА |
6 |
ЗИБЕРМАН |
9 |
ПЕТРОВ |
11 |
СЕМЕНОВ |
14 |
СЕРЕГИНА |
18 |
СИДОРОВ |
4 |
СЫЧЕВ |
1 |
УШАКОВ |
3 |
ФАДЕЕВ |
13 |
ЩУКИНА |
15 |
ЯКУШЕВ |
8 |
В дополнение к вышесказанному следует отметить, что индексных файлов может быть несколько. Столько сколько нужно для решения ваших задач. А вот основной файл всегда один. Этим избегается дублирование информации об объекте и облегчается ее корректировка. Но это же накладывает особые требования к системе программ обслуживающих основные и индексные файлы.
11.5. Создание индексного файла
Процесс первоначального создания индексного файла называется индексацией. При работе с базой данных существует невидимая информационная (реляционная) связь между двумя таблицами (файлами STUDENTS.DAT и STUDENTS.NTX), при этом индексный файл должен постоянно отслеживать состояние основного файла. Этот процесс необходимый атрибут ведения базы данных. Но файлы располагаются раздельно,
17
и по этой причине возникают различные ситуации, при которых индексный файл перестает соответствовать основному файлу. В этой ситуации приходится старый индексный файл удалять с диска, а на его месте создавать новый индексный файл. Этот процесс называется переиндексацией.
Пример 121. Для файла STUDENTS.DAT, расположенном в корневом каталоге диска A создать индексный файл STUDENTS.NTX, соответствующий табл. 49.
Закрыть основной файл (процедура Close);
Ниже приведен код программы, обеспечивающей индексацию файла STUDENTS.DAT. Имя индексного файла формируется автоматически из имени основного файла. Файл размещается в том же директории, что и основной.
PROGRAM PR121;
TYPE STUDENT = RECORD
TAB : LONGINT;
FIO : STRING[20];
DATA : STRING[8];
GRUP : STRING[7]; STEPA: REAL END;
INDEX = RECORD
FIO : STRING[20];
NAMBER: INTEGER END;
VAR MS: ARRAY[0..20] OF STUDENT; MI: ARRAY[0..20] OF INDEX;L:INDEX; I, J, N: INTEGER; FS: FILE OF STUDENT; ST,STI: STRING; FI: FILE OF
INDEX;
BEGIN {ЧТЕНИЕ ФАЙЛА В МАССИВ MS}
WRITELN('ВВЕДИТЕ ИМЯ ИНДЕКСИРУЕМОГО ФАЙЛА: '); READLN(ST); ASSIGN (FS, ST); RESET(FS);
N := -1; {НОМЕР ЗАПИСИ В ФАЙЛЕ} WHILE NOT EOF(FS)
DO BEGIN N := N+1;
READ(FS, MS[N]) END;
CLOSE(FS);
IF N >- 1 THEN BEGIN
{ЗАПОЛНЕНИЕ МАССИВА ИНДЕКСОВ MI} FOR I:=0 TO N
DO BEGIN MI[I].FIO := MS[I].FIO; MI[I].NAMBER := I END; {СОРТИРОВКА ИНДЕКСНОГО МАССИВА ПО КЛЮЧЕВОМУ ПОЛЮ
FIO}
FOR I := 0 TO N
DO FOR J := N DOWNTO I + 1
DO IF MI[J-1].FIO > MI[J].FIO
18
THEN BEGIN
L := MI[J-1]; MI[J-1] := MI[J]; MI[J] := L END;
{ФОРМИРОВАНИЕ ИМЕНИ ИНДЕКСНОГО ФАЙЛА} IF POS('.',ST) = 0
THEN STI := ST + '.NTX'
ELSE STI := COPY(ST, 1, POS('.', ST)) + 'NTX'; {ФОРМИРОВАНИЕ ИНДЕКСНОГО ФАЙЛА} WRITELN('ЖДИТЕ ИДЕТ ИНДЕКСАЦИЯ ФАЙЛА ...', STI); ASSIGN(FI, STI); REWRITE(FI);
FOR I := 0 TO N
DO WRITE(FI, MI[I]); CLOSE(FI)
END
ELSE WRITE ('ФАЙЛ ',ST, ' НЕ СОДЕРЖИТ НИ ОДНОЙ ЗАПИСИ!') END.
11.6. Работа с файлом произвольного доступа
Рассмотрим четыре важнейших режима работы с файлом прямого доступа: просмотр информации в файле; редактирование содержимого полей, существующих в файле записей; корректировку структуры файла, с сохранением информации; удаление записей; добавление новой записи.
Просмотр файла
Доступ к компонентам файла произвольного доступа может быть как последовательный, так и произвольный. Но при этом мы просматриваем записи в том порядке как они располагаются на диске в основном файле. Часто этот порядок нас не устраивает. Например хочется вывести сведения о студентах в алфавитном порядке их фамилий, или по группам, а в каждой группе упорядочить по фамилиям. Именно для этих целей и используются индексные файлы и процедура Seek.
Приведем порядок действий при просмотре файла произвольного доступа: Присвоить файлу имя (процедура Assign);
Открыть файл (процедура Reset) и запросить индексный файл; Присвоить индексному файлу имя (процедура Assign); Открыть индексный файл (процедура Reset);
Осуществить последовательный просмотр индексного файла начиная с первой записи до метки EOF, выполняя для каждой записи следующие два пункта.
Для каждой записи индексного файла, используя процедуру Seek установить указатель основного файла на соответствующую запись;
Считать нужный компонент (оператор read) основного файла и вывести на экран монитора;
Закрыть файлы (процедура Close).
Пример 122. Вывести на экран монитора в алфавитном порядке фамилий сведения о студентах, хранящихся в файле STUDENTS.DAT, расположенном в корневом каталоге диска A.
19
Именно для решения таких задач и создаются индексные файлы. В нашем случае будем использовать индексный файл STUDENTS.NTX.
PROGRAM PR122;
TYPE STUDENT = RECORD
TAB : LONGINT;
FIO : STRING[20];
DATA : STRING[8];
GRUP : STRING[7]; STEPA: REAL END;
INDEX = RECORD
FIO : STRING[20];
NAMBER: INTEGER END;
VAR L: INDEX; S: STUDENT; I, J, N: INTEGER;
FS: FILE OF STUDENT; ST, STI: STRING; FI: FILE OF INDEX; BEGIN {ЧТЕНИЕ ФАЙЛА В МАССИВ MS} WRITELN('ВВЕДИТЕ ИМЯ ОСНОВНОГО ФАЙЛА: '); READLN(ST); ASSIGN (FS, ST); RESET(FS);
WRITELN('ВВЕДИТЕ ИМЯ ИНДЕКСНОГО ФАЙЛА: '); READLN(STI); ASSIGN (FI, STI); RESET(FI);
WHILE NOT EOF(FI) {ПРОСМОТР ИНДЕКСНОГО ФАЙЛА} DO BEGIN
READ(FI, L); SEEK(FS, L.NAMBER); READ(FS, S);
WRITELN(S.TAB: 9, S.FIO: 15, S.DATA: 10, S.GRUP: 9 , S.STEPA: 9: 2) END;
CLOSE(FS); CLOSE(FI); END.
Редактирование записей
Одной из наиболее часто встречающихся задач, является редактирование записей основного набора данных. Например, Вахрушеву лишили стипендии. Для поиска записи используется индексный файл. Проблема возникает в том случае, если приходится изменить значение ключевого поля, которое является основой индексного файла. В этом случае по окончании редактирования записи основного файла следует внести изменения в индексный файл. Например, студентка с фамилией Вейнерман вышла замуж за студента Яковлева и изменила свою фамилию на Яковлеву. Одним из простейших способов решения этой проблемы является переиндексация. То есть повторное создание индексного файла. Это самый долгий по времени, но и самый надежный способ. Остальные способы мы рассматривать не будем, так это прерогатива специальных разделов информатики, а именно разработки программного обеспечения СУБД.
Пример 123. Вывести на экран монитора с целью коррекции информацию о студенте из файла STUDENTS.DAT, расположенном в корневом каталоге диска A. Поиск
20
студента осуществить по его фамилии. Откорректировать любое из полей или все поля записи, и сохранить изменения в файле STUDENTS.DAT.
Алгоритм функционирования программы следующий: Присвоить основному файлу имя (процедура Assign);
Открыть уже существующий на диске основной файл (процедура Reset); Присвоить индексному файлу имя (процедура Assign);
Открыть уже существующий на диске индексный файл (процедура Reset);
Ввести с клавиатуры имя студента сведения о котором вы хотите посмотреть и возможно откорректировать.
Читать индексный файл запись за записью пока не будет достигнута метка EOF, сверяя имя студента с указанным. При совпадении организовать диалог для коррекции информации.
Скорректированную запись занести в соответствующую компоненту рабочего
файла.
Если при коррекции было изменено ключевое поле, установить флаг FL в состояние TRUE.
Закрыть основной файл (процедура Close); Закрыть индексный файл (процедура Close);
Если ключевое поле изменялось (анализ FL), то сделать переиндексацию.
Код программы приведен ниже. В программе сформирована процедура IND, которая обеспечивает переиндексацию файла в случае изменения ключевого поля FIO.
PROGRAM PR123;
TYPE STUDENT = RECORD TAB : LONGINT;
FIO : STRING[20];
DATA : STRING[8];
GRUP : STRING[7]; STEPA: REAL END;
INDEX = RECORD
FIO : STRING[20];
NAMBER: INTEGER END;
VAR L: INDEX; I, J, N: INTEGER; ST, STI: STRING; STUD: STRING[20]; S: STUDENT; FS: FILE OF STUDENT; FI: FILE OF INDEX;
FL: BOOLEAN; {ФЛАГ: TRUE - ИЗМЕНИЛОСЬ КЛЮЧЕВОЕ ПОЛЕ} PROCEDURE IND; {ПРЕРИНДЕКСАЦИЯ ФАЙЛА}
VAR MS: ARRAY[0..20] OF STUDENT;MI: ARRAY[0..20] OF INDEX; BEGIN {ЧТЕНИЕ ФАЙЛА В МАССИВ MS}
ASSIGN (FS, ST); RESET(FS);
N := -1; {НОМЕР ЗАПИСИ В ОСНОВНОМ ФАЙЛЕ} WHILE NOT EOF(FS)
DO BEGIN
N:=N+1; READ(FS, MS[N])