Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

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

Поиск

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

Процедура CLOSE. Закрывает файл, однако связь файловой пере­менной с именем файла, установленная ранее процедурой ASSIGN, со­храняется. Формат обращения:

 

CLOSE (<ф.п.>)

 

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

Процедура RENAME. Переименовывает файл. Формат обращения:

 

RENAME (<ф.п.>, <новое имя>)

 

Здесь <новое имя> - строковое выражение, содержащее новое ими файла. Перед выполнением процедуры необходимо закрыть файл, если он ранее был открыт процедурами RESET, REWRITE или APPEND.

Процедура ERASE. Уничтожает файл. Формат обращения:

 

ERASE(<ф.п.>)

 

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

Следующий фрагмент программы показывает, как можно использо­вать процедуры RENAME и CLOSE при работе с файлами. Предполо­жим, что требуется отредактировать файл, имя которого содержит пере­менная NAME. Перед редактированием необходимо убедиться, что нуж­ный файл имеется на диске, и переименовать его - заменить расширение этого файла на .ВАК (страховочная копия). Если файл с таким расшире­нием уже существует, его надо стереть.

 

var

fi: text; {Исходный файл}

fo: text; {Отредактированный файл}

name: string;

name_bak: string;

k,i: word;

const

bak = '.bak';

........

{ Получить в name_bak имя файла с расширением.ВАК: }

k:= pos('.',name):

If k=0 then k:= length(name) + 1;

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

{ Проверить существование исходного файла: }

assign(fi,name):

{$I-} reset(fi);

If IOResult о 0 then halt; {Файл не существует}

close(fi):

{ Проверить существование.ВАК-файла: } assign(fo,name_bak);

reset(fo);

{$I+} If IOResult = 0 then

begin {Файл.ВАК существует}

close(fo);

erase(fo);

end;

{ Проверки закончены, подготовка к работе: }

rename(fi,name_bak);

reset(fi);

assign(fo,name);

rewrite(fo);

 

Обратите внимание: проверка на существование BAK-файла в дан­ном примере необходима, так как обращение

 

rename(fi,name_bak);

 

вызовет ошибку в случае, если такой файл существует.

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

 

FLUSH (<ф.п.>);

 

Любое обращение к файлу в Турбо Паскале осуществляется через некоторый буфер, что необходимо для согласования внутреннего пред­ставления файлового компонента (записи) с принятым в ДОС форматом хранения данных на диске. В ходе выполнения процедуры FLUSH все новые записи будут действительно записаны на диск. Процедура игнори­руется, если файл был инициирован для чтения процедурой RESET.

Функция EOF(<ф.п.>): BOOLEAN. Логическая функция, тести­рующая конец файла. Возвращает TRUE, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении - что файл исчерпан.

Процедура CHDIR. Изменение текущего каталога. Формат обраще­ния:

 

CHDIR (<путь>)

 

Здесь <путь> - строковое выражение, содержащее путь к устанав­ливаемому по умолчанию каталогу.

Процедура GETDIR. Позволяет определить имя текущего каталога (каталога по умолчанию). Формат обращения:

 

GETDIR(<ycmpoйcmвo>, <каталог>)

 

Здесь <устройство> - выражение типа WORD, содержащее номер устройства: 0 - устройство по умолчанию, 1 - диск А, 2 - диск В и т.д.;

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

Процедура MKDIR. Создает новый каталог на указанном диске. Формат обращения:

 

MKDIR(<каталог>);

 

Здесь <каталог> - выражение типа STRING, задающее путь к ката­логу. Последним именем в пути, т.е. именем вновь создаваемого каталога не может быть имя уже существующего каталога.

Процедура RMDIR. Удаляет каталог. Формат обращения:

 

RMDIR(<каталог>);

 

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

Функция IORESULT: WORD. Возвращает условный признак по­следней операции ввода-вывода.

Если операция завершилась успешно, функция возвращает ноль. Коды ошибочных операций ввода-вывода представлены в прил.З. Следует помнить, что IORESULT становится доступной только при отключенном автоконтроле ошибок ввода-вывода. Директива компилятора {$I-} отклю­чает, а директива {$I+} включает автоконтроль. Если автоконтроль от­ключен, а операция ввода-вывода привела к возникновению ошибки, устанавливается флаг ошибки и все последующие обращения к вводу-вы­воду блокируются, пока не будет вызвана функция IORESULT.

Ряд полезных файловых процедур и функций становится доступным при использовании библиотечного модуля DOS.TPU, входящего в стан­дартную библиотеку TURBO.TPL. Эти процедуры и функции указаны ниже. Доступ к ним возможен только после объявления USES DOS в начале программы (подробнее о работе с модулями см. гл.9).

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

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

Текстовый файл трактуется в Турбо Паскале как совокупность строк переменной длины. Доступ к каждой строке возможен лишь последова­тельно, начиная с первой. При создании текстового файла в конце каждой записи (строки) ставится специальный признак EOLN (End Of LiNe -конец строки). а в конце всего файла - признак EOF (End Of File - конец файла). Эти признаки можно протестировать одноименными логически­ми функциями (см. ниже). При формировании текстовых файлов исполь­зуются следующие системные соглашения:

EOLN - последовательность кодов ASCII 13 (CR) и 10 (LF);

EOF - код 26 стандарта ASCII.

Для доступа к записям применяются процедуры READ, READLN, WRITE, WRITELN. Они отличаются возможностью обращения к ним с переменным числом фактических параметров, в качестве которых могут использоваться символы, строки и числа. Первым параметром в любой из перечисленных процедур может стоять файловая переменная. В этом случае осуществляется обращение к дисковому файлу или логическому устройству, связанному с переменной процедурой ASSIGN. Если файло­вая переменная не указана, происходит обращение к стандартным файлам Input и Output.

Процедура READ. Обеспечивает ввод символов, строки чисел. Фор­мат обращения:

 

READ (<ф.п.>,<сп.ввода>);

 

или

 

READ (<сп.ввода>);

 

Здесь <сп.ввода> - список ввода: последовательность из одной или более переменных типа CHAR, STRING, а также любого целого или вещественного типа.

При вводе переменных типа CHAR выполняется чтение одного сим­вола из файла и присваивание считанного значения переменной. Если перед выполнением чтения указатель файла достиг конца очередной стро­ки. то результатом чтения будет символ CR (ASCII код 13), а если достиг­нут конец файла, то - символ EOF (код 26). При вводе с клавиатуры символ CR вводится при нажатии на клавишу «Ввод», а символ EOF - при одновременном нажатии клавиш CTRL и Z.

При вводе переменных типа STRING количество считанных процедурой и помещенных в строку символов равно максимальной длине стро­ки, если только раньше не встретились символы CR или EOF. В этом случае сами символы CR и EOF в строку не помещаются. Если количество символов во входном потоке данных больше максимальной длины строки, «лишние» символы до конца строки отбрасываются, а новое обращение к READ возвращает пустую строку. Таким образом, процедура READ не в состоянии прочесть последовательность строк: первая строка будет прочи­тана нормально, а все последующие окажутся пустыми. Для ввода после­довательности строк нужно использовать процедуру READLN (см. ниже).

При вводе числовых переменных процедура READ вначале выделя­ет подстроку во входном потоке по следующему правилу: все ведущие пробелы, символы табуляции и маркеры конца строк EOLN пропускают­ся; после выделения первого значащего символа, наоборот, любой из пе­речисленных символов или символ EOF служат признаком конца под­строки. Выделенная таким образом подстрока затем рассматривается как символьное представление числовой константы соответствующего типа и преобразуется во внутреннее представление, а полученное значение присваивается переменной. Если в подстроке был нарушен требуемый формат представления численной константы, возникает ошибка ввода-вывода. Если при пропуске ведущих пробелов встретился символ EOF, перемен­ная получает значение 0. Отметим, что в Турбо Паскале не предусмотрен ввод шестнадцатиричных констант.

Процедура READ прекрасно приспособлена к вводу чисел. При об­ращении к ней за вводом очередного целого или вещественного числа процедура «перескакивает» маркеры конца строк, т.е. фактически весь файл рассматривается ею как одна длинная строка, содержащая текстовое представление чисел. В сочетании с проверкой конца файла функцией EOF процедура READ позволяет организовать простой ввод массивов данных, например, так:

 

const

N = 1000; { максимальная длина ввода }

var

f: text;

m: array [1..N] of real;

i: Integer;

BEGIN

assign(f, 'prog.dat');

reset(f);

i:= 1;

while not EOF(f) and (I <= N) do

begin

read(f,m[i]);

inc(i);

end;

сlоse(f);

end.

 

Процедура READLN. Обеспечивает ввод символов, строк и чисел. Эта процедура идентична процедуре READ за исключением того, что после считывания последней переменной оставшаяся часть строки до мар­кера EOLN пропускается, поэтому следующее обращение к READLN или READ начинается с первого символа новой строки. Кроме того, эту про­цедуру можно вызвать без параметра <сп.ввода> (см. процедуру READ), что приведет к пропуску всех символов текущей строки вплоть до EOLN.

Процедура WRITE. Обеспечивает вывод информации в текстовый файл или передачу ее на логическое устройство. Формат обращения:

 

WRITE(<ф.п.>,<сп.вывода>) или WRITE(<сп.вывода>);

 

Здесь <сп.вывода> - список вывода: последовательность из одного или более выражений типа CHAR, STRING, BOOLEAN, а также любого целого или вещественного типа.

Файловая переменная <ф.п.>, если она указана, должна быть пред­варительно описана как переменная типа TEXT и связана с именем файла или логическим устройством процедурой ASSIGN. Если файловая пере­менная отсутствует, подразумевается вывод в стандартный файл OUTPUT, который обычно связан с экраном ПК.

Любой элемент списка вывода может иметь форму

 

OutExpr [: MInWidth [: DecPlaces ] ]

 

Здесь OUTEXPR - выводимое выражение;

MINWIDTH, DECPLACES - выражения типа WORD (квадратные скобки означают возможность отсутствия заключенных в них парамет­ров).

Подпараметр MINWIDTH, если он присутствует, указывает мини­мальную ширину поля, в которое будет записываться символьное пред­ставление значения OUTEXPR. Если символьное представление имеет меньшую длину, чем MINWIDTH, оно будет дополнено слева пробелами, если - большую длину, то подпараметр MINWIDTH итерируется и вы­водится необходимое число символов.

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

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

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

При выводе логических выражений в зависимости от их значения выводятся строки TRUE или FALSE. (Ввод логических констант проце­дурами READ или READLN не предусмотрен).

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

Процедура WRITELN. Эта процедура полностью идентична проце­дуре WRITE за исключением того, что выводимая строка символов завер­шается кодами CR и LF. При вызове WRITELN можно опускать параметр <сп.вывода>: в этом случае в файл передается маркер EOLN, что при выводе на экран приведет к переводу курсора в начало следующей строки.

Логическая функция EOLN. Возвращает TRUE, если во входном текстовом файле достигнут маркер конца строки. Формат обращения:

 

EOLN(<ф.n.>);

 

Если параметр <ф.п.> опущен, функция проверяет стандартный файл INPUT.

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

Логическая функция SEEKEOLN. Пропускает все пробелы и знаки табуляции до маркера конца строки EOLN или до первого значащего символа и возвращает TRUE, если маркер обнаружен. Формат обраще­ния;

 

SEEKEOLN(<ф.п.>);

 

Если параметр <ф.п.> опущен, функция проверяет стандартный файл INPUT,

Логическая функция SEEKEOF. Пропускает все пробелы, знаки табуляции и маркеры конца строки EOLN до маркера конца файла или до первого значащего символа и возвращает TRUE, если маркер обнару­жен. Формат обращения:

 

SEEKEOF(<ф.п.>);

 

Если параметр <ф.п.> опущен, функция проверяет стандартный файл INPUT.

В следующем примере, иллюстрирующем работу с текстовым фай­лом, подсчитывается общее количество символов в файле и результат делится на 40000 - таким способом можно оценить объем рукописи в так называемых учетно-издательских листах:

 

var

f: text;

s: string;

const

Sum: longint = 0; {Здесь будет количество символов} BEGIN

Writе('Имя файла: '); {Запросить}

Readln(s); {и ввести имя файла}

assign(f,s);

Reset(f); {Открыть файл}

while not EOF(f) do {Подсчитать}

begin {количество}

Readln(f,s); {символов}

inc(Sum, Length(s)) {в тексте}

end; {этой программы}

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

Writeln('Объем - ',Sum/40000:6:2,' уч.изд.л.');

END.

 

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

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

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

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

 

READ (<ф.п.>,<сп.ввода>);

 

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

Файловая переменная <ф. п. > должна быть объявлена предложением FILE OF... и связана с именем файла процедурой ASSIGN. Файл необ­ходимо открыть процедурой RESET. Если файл исчерпан, обращение к READ вызовет ошибку ввода-вывода.

Процедура WRITE. Используется для записи данных в типизиро­ванный файл. Формат обращения:

 

WRITE (<ф.п.>,<сп.вывода>);

 

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

Процедура SEEK. Смещает указатель файла к требуемому компо­ненту. Формат обращения:

 

SEEK (<ф. п. >,<N компонента>);

 

Здесь <N компонента> - выражение типа LONGINT, указывающее номер компонента файла.

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

Функция FILESIZE. Возвращает значение типа LONGINT, которое содержит количество компонентов файла. Формат обращения:

 

FILESIZE(<ф.п.>);

 

Функцию нельзя использовать для текстовых файлов. Чтобы пере­местить указатель в конец файла, можно написать:

 

seek(FileVar, FileSize(FileVar));

 

где FILEVAR - файловая переменная.

Функция FILEPOS. Возвращает значение типа LONGINT, содер­жащее порядковый номер компонента файла, который будет обрабаты­ваться следующей операцией ввода-вывода. Формат обращения:

 

FILEPOS(<ф.п.>);

 

Функцию нельзя использовать для текстовых файлов. Первый ком­понент файла имеет порядковый номер 0.

Нетипизированные файлы

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

При инициации нетипизированного файла процедурами RESET или REWRITE можно указать длину записи нетипизированного файла в байтах. Например, так:

 

var

f: file;

..........

assign(f, 'myfile.dat');

reset(f,5l2);

 

Длина записи нетипизированного файла указывается вторым параметром при обращении к процедурам RESET или REWRITE, в качестве которого может использоваться выражение типа WORD. Если длина за­писи не указана, она принимается равной 128 байтам.

При работе с нетипизированными файлами могут применяться все процедуры и функции, доступные типизированным файлам, за исключе­нием READ и WRITE, которые заменяются соответственно высокоскоро­стными процедурами BLOCKREAD и BLOCKWRITE. Для вызова этих процедур используются следующие предложения:

 

BLOCKREAD(<ф.п.>,<буф>,<N>[,<NN>]); BLOCKWRITE(<ф.п.>,<буф>,<N>[,<NN>]);

 

Здесь <буф> - буфер: имя переменной, которая будет участвовать в обмене данными с дисками;

<N> - количество записей, которые должны быть прочитаны или записаны за одно обращение к диску;

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

За одно обращение к процедурам может быть п­ередано до N*RECS байт, rppRECS - длина записи нетипизированного файла. Передача идет, начиная с первого байта переменной <буф>. Программист должен позабо­титься о том, чтобы длина внутреннего представления переменной <буф> была достаточной для размещения всех N*RECS байт при чтении инфор­мации с диска. Если при чтении у казана переменная <буф> недостаточной длины или если в процессе записи на диск не окажется нужного свобод­ного пространства, возникнет ошибка ввода-вывода, которую можно за­блокировать, указав необязательный параметр <NN> (переменная типа WORD).

После завершения процедуры указатель смещается на <NN> запи­сей. Процедурами SEEK, FILEPOS и FILESIZE можно обеспечить до­ступ к любой записи нетипизированного файла.

 

 



Поделиться:


Последнее изменение этой страницы: 2017-02-19; просмотров: 592; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.117.91.116 (0.009 с.)