Программирование в среде Турбо Паскаль (Поляков, Круглов) - страница 150

| BEGIN

| >ReadLn( FileName ); { считывается имя файла }

| >Assign( f, FileName );

| >SetTextBuf( f, Buffer ); { назначение буфера }

| >Rewrite( f ) { открытие файла f }

| END;


Рис. 12.3

- 234 -


| VAR

| > ff : Text;

| BEGIN { основная часть примера }

| > GetFileAndOpenIt( ff );

| > Write{ ff, ... ); { попытка записи в файл ff }

| { Дальше неважно, что будет. Все равно результат уже }

| { будет неверный. }

| END.


Рис. 12.3 (окончание)

Дело в том, что локальная переменная Buffer (а именно в ней мы размещаем буфер открываемого файла) существует лишь во время выполнения процедуры. После окончания она исчезает, область буфера становится общедоступной и наверняка очень быстро заполнится совершенно «посторонними» значениями, а переданный в вызывающий блок файл f (ff) будет вести себя непредсказуемо. При всем этом не возникнет ни ошибки компиляции, ни ошибки во время счета.

Если размещать буфер в статической переменной, то он «съедает» часть области данных или стека. А они ограничены размером 64K, что вовсе, не так много. Выгоднее было бы размещать буфер в динамической памяти (куче). Для этого надо объявить указатель на место буфера в куче (рис. 12.4).


| VAR

| >ft : Text; { файл типа текст }

| >PBuf : Pointer; { ссылка на буфер }

| CONST

| >BufSize=1024; { размер буфера }

| BEGIN

| >Assign( ft, 'TEXTFILE.DOC' );

| >GetMem( PBuf, BufSize); { в памяти отводится }

| >{ блок размером с буфер }

| >SetTextBuf( ft, PBuf^,BufSize ); { Задается буфер в }

| >{ динамической памяти. }

| >Reset( ft ); { открытие файла }

| >{ . . . } { работа с файлом ft }

| >Close( ft };

| >FreeMem(Pbuf, BufSize); { Буфер удаляется из }

| >{ памяти (кучи). }

| END.


Рис. 12.4

- 235 -

В этом случае нужно отводить и освобождать память под буфер, а в SetTextBuf обязательно указывать его размер, так как блок памяти с началом в PBuf^ «не знает» своего размера.

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

12.6.1.2.Процедура Append(VAR f : Text). Эта процедура служит для специального открытия файлов для записи. Она применима только к уже существующим физическим файлам и открывает их для дозаписи, т.е. файл не стирается, как при вызове Rewrite, а подготавливается к записи элемента в конец файла. Если Append применяется к несуществующему файлу, то возникнет ошибка времени счета. Новый файл может быть создан только процедурой Rewrite. Как автоматически выбрать соответствующую процедуру открытия файла — Append или Rewrite, описано в разд. 12.11.