Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
TURBO_PASCAL.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
8 Мб
Скачать
☆

12.9.1. Опрос размеров файлов и позиции в них

  1. Функция FileSize( VAR f) : LongInt. Эта функция возвращает реальное число записей в открытом файле f. Применительно к рис. 12.8, эта функция вернула бы значение n. Для пустого файла возвращаемое значение равно 0.

Функция FilePos( VAR f ) : LongInt Эта функция возвращает нашу текущую позицию в файле f. Файл должен быть открытым. Позиция в файле — это номер условной границы (см. рис. 12.8). Если файл только что открылся, то текущей позицией будет граница с номером 0. Это значит, что можно прочитать (или записать) запись с реальным номером (0+1)=1. После, например, ее прочтения позиция переместится на границу 1, и следующей можно будет прочитать запись (1+1)=2 и т.д. После прочтения последней записи в файле с реальным номером n позиция совпадает с границей с таким же номером n. Дальше записей нет. Поэтому, если FilePos {256} возвратила значение, равное FileSize, то мы находимся в конце файла за последней записью:

if FilePos( f ) = FileSize( f ) then { Все! Конец файла }

Все сказанное можно теперь сформулировать следующим образом:

  1. В самом начале файла функция FilePos возвращает значение 0.

  2. В самом конце файла функция FilePos возвращает число, равное реальному количеству записей в файле (FileSize).

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

12.9.2. Позиционирование в файлах

Операция назначения текущей позиции в файле (позиционирование) производится процедурой Seek. Процедура Seek( VAR f; N : Longint ) непосредственно реализует прямой доступ в файл f. Файл должен быть открыт. Разберем механизм работы процедуры, используя рис. 12.8. В параметре N должен быть задан номер условной границы между записями. Чтобы работать с записью, имеющей реальный номер 3, мы должны задать позицию на границе перед ней, т.е. на границе с номером N=(3-1)=2. Чтобы прочитать или записать первую запись, должны задать N=0:

Seek( f, 0 );

где 0 — номер границы перед первой записью. А в случае, когда необходимо, чтобы позиция имела номер последней границы (а он совпадает с числом записей на последний момент времени), следует воспользоваться вызовом:

Seek( f, FileSize( f ) ).

Доступ к последней записи в файле:

Seek( f, FileSize( f ) - 1 ).

В принципе, правила назначения позиции процедурой Seek такие же, как и правила вычисления FilePos, только направлены на изменение позиции, а не на ее анализ.

На рис. 12.9 приводится пример, в котором меняются местами первый и последний компоненты. Обратите внимание на то, как после считывания последнего компонента мы вернулись на позицию назад, чтобы переписать этот же последний компонент. {257}

{ ПРИМЕР ТОГО, КАК ПОМЕНЯТЬ МЕСТАМИ ЗАПИСИ В ФАЙЛЕ }

TYPE

Dim = Array [1..3] of Char; { тип компонента файла }

VAR

f : File of Dim; { компонентный файл }

ff : File; { бестиповый файл }

Dfirst, Dlast : Dim; { массивы типа Dim } FS : LongInt; { длина файла f }

CONST

St: String[11*3]= 'AAA—BBB—CCC—DDD—EEE—FFF';

{Две процедуры для создания файла из 11 массивов типа }

{Dim и его загрузки после модификации прямым доступом. }

{Содержимое массивов представлено строкой длины 11*3=33 }

PROCEDURE Save.St;

BEGIN

Assign( ff, 'DIMFILE.DAT' ); Rewrite( ff, 3 );

BlockWrite( ff, St[1], 11 ); Close( ff )

END;

PROCEDURE Load.St;

BEGIN

Assign( ff, 'DIMFILE.DAT' ); Reset(ff, 3);

BlockRead( ff, St[1], 11 ); Close( ff )

END;

BEGIN

WriteLn( 'Стартовое содержимое файла: ', St );

Save St;

Assign( f, 'DIMFILE.DAT' ); { связывание f с диском } Reset( f ); { открытие файла f }

FS := FileSize( f ); { запоминание длины файла }

if FS < 2 then begin

WriteLn('Маловато записей в файле для примера!’); Halt { выход из программы }

end; {if}

Read( f, Dfirst ); { считывается первый массив в файле }

Seek( f, FS-1 ); { переход к последней записи }

Read( f, Dlast ); {считывается последний массив }

Seek( f, FilePos(f)-1 ); { назад на одну запись }

Write( f, Dfirst ); { первый массив замещает последний }

Seek{ f, 0 ); { переход в самое начало файла }

Write( f, Dlast ); { последний массив замещает первый }

Close( f ); { закрытие модифицированного файла }

Load St; WriteLn { 'Итоговое содержимое файла: ', St );

ReadLn { пауза до нажатия клавиши ввода }

END.

Рис. 12.9 {258}

Напомним, что процедуры Write/Read и BlockWrite/BlockRead при каждом вызове перемещают границу на число прочитанных или записанных записей (компонентов или блоков).

Вызов Seek со значением N, большим чем FileSize, вызовет ошибку ввода-вывода.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]