Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Паскаль-конспект ИНФОРМАТИКА.doc
Скачиваний:
59
Добавлен:
09.04.2015
Размер:
639.49 Кб
Скачать

10.6. Операции над файлами

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

Операции по установке связей между файловой переменной и внешним устройством или внешним файлом на магнитном носителе, т.е. операции по открытию файлов, а так же операции по «развязке» этих связей, т.е. закрытию файлов реализуются процедурами:

Assign Rewrite Close

Reset Append Flush

Связывание файловой переменной с именем файла осуществляется обращением к встроенной процедуре ASSIGN:

Assign( файловая переменная, имя файла ).

Здесь имя файла – переменная или константа типа String. Имя должно быть написано в соответствии с правиламиMSDOS, может включать путь и не должно превышать 79 символов. Если строка имени пустая, осуществляется связь со стандартным файлом ввода или вывода (как правило, консолью).

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

Примеры:

1) Установление связи с внешним файлом на магнитном носителе. В этом случае имя внешнего файла представляет собой спецификацию файла:

Assign (Namefaile,’C:\direct\tfile.dat’);

Assign (Kandy,’D:\direct\sadry\fio.dat’);

2) Установление связи программного файла с внешним устройством. Для ввода с клавиатуры, если далее следует операция считывания данных; либо вывода на экран дисплея, если далее следует операция записи данных:

Assign(inputfile,’CON’);

3) Для вывода данных на печатающее устройство (допускается подключение до трёх печатающих устройств): LPT1 (синонимPRN),LPT2 иLPT3.

Assign(Outhut,’LPT1’ );

4) Для последующего обмена информацией по коммуникационным каналам. Смысл записи псевдофайлов COM1 (или синонимAUX) либо СОМ2 определяется конкретным внешним устройством. Например, это может быть «мышь» или графопостроитель (плотер), либо узел при сетевой связи компьютеров:

Assign(interfile,’COM1’ );

5) Установление связи с фиктивным внешним устройством. Например, при отладке программы вывод информации блокируется, но конкретная работа программы при этом не нарушается:

Assign(myfile,’NUL’);

Реализация операций обмена данными

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

Эта операция в общем случае выполняется следующими процедурами:

Reset(файловая переменная, размер записи);

Reset(файловая переменная);

Rewrite(файловая переменная);

Rewrite(файловая переменная, размер записи);

Append(файловая переменная);

Основные процедуры обработки файлов

Reset (F)– подготовка чтения файлаF. При этом указатель позиции помещается в начало файла. Если файл не пустой, то переменнойFприсваивается значение его первого компонента, а функцияeof(F) =false. Параметр «размер записи» указывается лишь в случае обработки нетипизированных файлов. В результате обработки процедурыReset, если соответствующий файл обнаружен, текущий указатель устанавливается в начале файла, т.е. на нулевом элементе файла. Если же внешний файл не обнаружен, то вырабатывается условие ошибки. Оператор процедурыreset(f) переводит файлfв режим чтения и устанавливает окно на первую позицию файла. Оператор процедурыread(f,v) присваивает переменнойvзначение текущей компоненты из файлаfи передвигает окно на следующую позицию. Процедураresetможет применятся к одному и тому же файлу несколько раз и при этом содержимое его не изменяется.

Rewrite (F)– подготовка записи в файл. Текущее значение файловой переменнойFстановится равнымemply(пустой). Функцияeof(F) =true. Может записывать новый файл. Оператор процедурыrewrite(f) устанавливает файл в режим записи, если раньше в этот файл были записаны какие-то данные, то они теряются. Оператор процедурыwrite(f,x) записывает в файлfочередную компонентуx, после чего окно сдвигается на следующую позицию. Общий вид оператора подготовки запист:

Rewrite(файловая переменная, [имя файла]);

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

Непосредственные операции ввода–вывода выполняются процедурами readиwrite. Обращения к этим процедурам:

Read(файловая переменная, выражение);

Write(файловая переменная, выражение);

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

write(файловая переменная);

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

В принципе все операции создания и чтения последовательного файла можно сформировать из приведённых простых процедур и стандартной функции eof. На практике же часто полезно совмещать перемещение по файлу с доступом к буферной переменной. Поэтому введём две новые процедурыReadиWriteследующим образом:

Read(F,X), где Х – некоторая переменная.

Write(F,Y), гдеY– некоторое выражение.

ReadиWrite– специальные процедуры, распространённые для работы с переменным числом параметров (Х1,Х2,…,ХN– переменные, аY1,Y2,…,YN– выражения).

Обращение к функции Read(F,X1,…,XN) эквивалентно конструкции

begin

Read (F,X1);

Read (F,X2);

…………….

Read(F,XN)

end;

к функции Write(F,Y1,Y2,…,YN) - эквивалентно конструкции

begin

Write (F,Y1);

Write (F,Y2);

…………….

Write(F,YN)

end;

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

While Not EOLN (имя) Do,

а для перехода на новую строку файла – оператор Readln(имя).

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

Для чтения файла необходимо выполнить следующие действия:

открыть файл для чтения ( процедура Reset);

ввести данные файла в программу ( процедура Read);

закрыть файл для чтения ( процедура Close)

Общая форма чтения файла:

Reset( файловая переменная, [имя файла] );

……………..

Read( файловая переменная, параметры );

……………..

Close( файловая переменная );

Читать файл можно только с начала, предварительно открыв его на чтение процедурой Reset.

Порядок выполнения операций чтения.

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

Пример. При открытии файла с именем С для чтения соответствующая буферная переменная принимает значение первой записи файла С. Если файл пуст, тоEOF(C) =True, а значение буферной переменной не определено. Для чтения очередной записи из файла С необходимо выполнить процедуруRead(C). При этом считанная запись станет доступной через буферную переменную. При окончании записи элементов в файл С его необходимо закрыть при помощи процедурыClose(C). При этом файл С сохраняется на внешнем носителе, если при его открытии на запись было указано внешнее имя.

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

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

Порядок выполнения операции записи.

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

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

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

Встроенная процедура rewriteинициирует запись информации в файл.

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

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

Если же соответствующие файлы на внешнем носителе не обнаружены, то процедуры AppendиReWriteоткрывают новый файл с указанным именем, соответствующим заданной файловой переменной.

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

Close (файловая переменная).

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

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

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

Процедура Rename(файловая переменная, новое имя). Переименовывает файл. Перед выполнением процедурыRenameнеобходимо закрыть файл, если он ранее был открыт процедурамиReset,ReWrite,Append. Внешний файл, с которым связана файловая переменная, получает новое имя, заданное параметром «новое имя». Этот параметр по своим характеристикам аналогичен параметру «имя файла» в процедуреAssign.

Процедура Erase(файловая переменная) уничтожает файл.

Erase(файловая переменная).

Перед выполнением процедуры необходимо закрыть файл, если он ранее был открыт процедурами Reset,ReWriteилиAppend.

Процедура Flush(файловая переменная). Поскольку обмены с файлами реализуются через некоторый внутренний буфер в оперативной памяти, то в процессе обработки информации могут возникать ситуации задержки данных, то есть «застревание» информации в буфере. Если же в процессе обработки информации не требуется пополнять буфер, то есть считывать следующий элемент, либо разбивать находящиеся в буфере данные на порядки, то с помощью процедурыFlash(файловая переменная) выполняется принудительный сброс информации при записи и очистка буфера. ПроцедураFlushигнорируется, если файл был инициирован для чтения процедуройReset. Ценность этой процедуры сомнительна, так как все её функции реализуются процедуройClose, при выполнении которой закрытие файла автоматически сопровождается ликвидацией соответствующего буфера.

При завершении программы автоматически выполняется закрытие всех открытых в программе файлов.

Процедура ChDir(путь) – излагает текущий каталог (директорию). Здесь «путь» – строковое выражение, содержащее путь к установленному по умолчанию каталогу. Параметр. «путь» может быть только типаString. Таким образом,ChDirустанавливает новый текущий каталог, путь к которому находится в процедуре «путь».

Процедура GetDir (устройство, каталог) позволяет определить имя текущего каталога (каталога по умолчанию). Здесь «устройство» - выражение типаWord, содержащее номер устройства:

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

1 – диск А,

2 – диск В и т. д.

Здесь «каталог» - переменная типа String, которая определяет путь к текущему каталогу на указанном диске.

Процедура MkDir(каталог) создаёт новый каталог на указанном диске. Здесь «каталог» - выражение типаString, задающее путь к каталогу. Последним именем в пути, то есть именем вновь создаваемого каталога, не может быть имя уже существующего каталога.

Процедура RmDir(каталог) удаляет каталог. Удалённый каталог должен быть пустым, то есть не содержать файлов или имён каталогов нижнего уровня.

Функция IOResult:Wordвозвращает признак последней операции ввод – вывод. Если операция завершилась успешно, функция возвращает ноль. Эта функция становится доступной только при отключённом автоконтроле ошибок ввода – вывода. Директива компилятора { $1-} отключает, а { $1+} включает автоконтроль. Если автоконтроль отключён и операция ввода – вывода привела к возникновению ошибки, устанавливается флаг ошибки и все последующие обращения к вводу – выводу блокируются, пока не будет вызвана функцияIOResult.

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

Функция DiskFree(диск) :Longint. Возвращает объём в байтах свободного пространства на указанном диске. В этой функции «диск» - номер диска:

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

1 – диск А,

2 – диск В и т. д.

Функция возвращает значение -1, если указан номер несущего диска.

Функция DiskSize(диск):Longint. Возвращает полный объём диска в байтах ( -1, если указан номер несуществующего диска).

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

Read Write

Readln Writeln

BlockRead BlockWrite

Пример. Работа с файломFIZAP.

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

Внешнее имя РР71.dat

Program PP71;

Type ZAP = Record

FIO : Array [1…10] of Char;

GOD: integer

end; {of record}

F = File;

Var FIZAP: F;

A, B : ZAP;

J, I : integer;

begin Assign (FIZAP, `C: \ Program \ t – pas \ pp71.dat);

ReWrite (FIZAP, 12);

For Y : = 1 to 3 do

Begin Write (`=>`);

For I = 1 to 10 do

read (B. FIO [I]);

Readln (B. God);

BlockWrite (FIZAP, B, 1)

end;

close (FIZAP);

Reset (FIZAP, 12);

For J: = 1 to 3 do

begin BlockReadln (FIZAP, A, 1);

Writeln (J : 2, `-ая запись `, A. FIO, A. GOD: 5);

end

end.

Протокол работы программы:

Иванов 1967

Петров 1970

Сидоров 1968

1 – ая запись Иванов 1967

2 – ая запись Петров 1970

3 – ая запись Сидоров 1968

Пример.Программа формирует файл и сохраняет его на внешнем носителе, что обеспечивается заданием внешнего имениPP74.datпри открытии файла на запись. Ввод исходной информации во внешний файл в программе осуществляется до тех пор, пока не будет введена фамилия, состоящая из десяти звёздочек (признак конца ввода). Это сделано для того, чтобы пользователю не надо было предварительно подсчитывать количество вводимых записей.

Program PP74;

Type ZAP = Record

FIO : Array [1…10] of Char;

GOD: integer

end; {of record}

F = File;

Var FIZAP: F;

A : ZAP;

I : integer;

begin Assign (FIZAP, `C: \ t – pas \ pp74.dat);

ReWrite (FIZAP, 12);

Repeat

Write (`=>`);

For I = 1 to 10 do

read (A. FIO [I]);

Readln (A. God);

BlockWrite (FIZAP, A, 1)

Until A . FIO = `**********`;

close (FIZAP);

Reset (FIZAP, 12);

I: = 1;

Repeat BlockRead (FIZAP, A, 1);

Writeln (I : 2, `-ая запись `, A. FIO, A. GOD: 5);

I : = I+1

Until A . FIO = `**** `;

end.

Протокол работы программы:

Иванов 1966

Петров 1970

Сидоров 1972

Пушкин 1968

1 – ая запись

2 – ая запись

и т. д.

Пример. В программе из внешнего файла с именемPP75.datудаляются все записи, соответствующие людям, родившимся до 1970 года. Для этого используется рабочий файл с внешним именем `PPR.dat`, в который сначала последовательно переписываются из внешнего файла все оставляемые записи, затем внешний файл открывается на запись, рабочий файл – на чтение и всё содержимое рабочего файла переписывается во внешний файл. При этом для контроля работы программы оставляемые записи выдаются на терминал.

Program PP75;

Type ZAP = Record

FIO : Array [1…10] of Char;

GOD: integer

end; {of record}

F = File;

Var FIZAP, RB: FPK;

A : ZAP;

I : integer;

{Ввод данных в файл FIZAP}

begin Assign (FIZAP, `C: \ t – pas \ pp75.dat);

ReWrite (FIZAP, 12);

Repeat

Write (`=>`);

For I = 1 to 10 do

read (A. FIO [I]);

Readln (A. God);

BlockWrite (FIZAP, A, 1)

Until A . FIO= `**********`; {здесь год должен быть >1970}

close(FIZAP);

{контрольный вывод содержимого обрабатываемого файла FIZAP}

Writeln;

Writeln(`обрабатываемый файл :`);

Reset(FIZAP, 12);

I: = 1;

Repeat BlockRead (FIZAP, A, 1);

Writeln (I : 2, `-ая запись `, A. FIO, A. GOD: 5);

I : = I+1

Until A . FIO = `**********`;

close(FIZAP);

{Перепись из обработанного файла FIZAPв рабочий файлRBлюдей, родившихся не ранее 1970 года}

Reset (FIZAP, 12);

Assign (RB, `C: \ Language\ t – pas \ pp75.dat);

ReWrite (RB, 12);

Repeat

BlockRead (FIZAP, A, 1);

If A . GOD >= 1970 Chen BlockWrite (RB, A, 1)

Until A . FIO = `**********`;

close (RB);

close(FIZAP);

{ контрольный вывод содержимого обрабатываемого файла RB}

Writeln;

Writeln (`рабочий файл :`);

Reset (RB, 12);

I: = 1;

Repeat BlockRead (RB, A, 1);

Writeln (I : 2, `-ая запись `, A. FIO, A. GOD: 5);

I : = I+1

Until A . FIO = `**********`;

close(RB);

{Перепись из рабочего файла RBв обрабатываемый файлFIZAP}

Reset (RB, 12);

ReWrite (FIZAP, 12);

Repeat

BlockRead (RB, A, 1);

BlockWrite (FIZAP, A, 1)

Until A . F1O = `**********`;

close (RB);

close (FIZAP);

{ контрольный вывод содержимого обрабатываемого файла}

Writeln;

Writeln(`обработанный файл :`);

Reset(FIZAP, 12);

I: = 1;

Repeat BlockRead (FIZAP, A, 1);

Writeln (I : 2, `-ая запись `, A. FIO, A. GOD: 5);

I : = I+1

Until A . FIO = `**********`;

close (FIZAP);

Writeln (`ok`)

end.

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

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

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

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

Program Z3;

Type ZAP = Record

NOV : Array [1…10] of Char;

Cena : integer

end; {of record}

Tovar = File of ZAP;

Var Nov, Star: Tovar;

B:ZAP;

I:integer;

Begin

(*ввод с терминала полей новой записи*)

Write (`=>`);

For I := 1 to 10 do

read (B. Nazv [I]);

Readln(B.Cena);

(*открытие файлов*)

Reset (Star, Star.dat);

ReWrite (Nov, Nov.dat);

(*вставка новой записи*)

Whileусловие окончания ввода записейdo

Операторы ввода записей

Close(Nov):

(*перепись данных из нового файла в старый и их печать*)

Reset (Nov, Nov.dat);

ReWrite (Star, Star.dat);

Repeat

Операторы присваивания значений записей нового файла записям старого файла.

Writeln(B.Nazv,B.Cena) (*вывод на терминал*)

Until B. Nazv = `**********`;

Close (Star)

end.