| 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.