Обработка ошибок. Прямой доступ к потокам. Использование потоков с произвольными данными.
При обнаружении ошибки поток вызывает свой метод TStream.Error, который определяет необходимую реакцию программы. По умолчанию этот метод просто записывает информацию об ошибке в поля TStream.Status и TStream.ErrorInfo.
Поле Status определяет тип ошибки, в соответствии со следующими константами модуля Objects:
const stOk = 0; {Нет ошибки} stError =-1; {Ошибка доступа} stInitError =-2; {Ошибка инициации потока} stReadError =-3; {Чтение за концом потока} stWriteError =-4; {Нельзя расширить поток} stGetError =-5; (Get для незарегистрированного объекта} stPutError =-6; {Put для незарегистрированного объекта}
Поле ErrorInfo определено только для Status – -5 или Status – -6: в первом случае оно содержит регистрационный номер, полученный из потока и не обнаруженный в регистрационном списке; во втором – смещение ТВМ незарегистрированного объекта, который программа пытается поместить в поток.
Сразу после обнаружения ошибки Turbo Vision блокирует все операции с потоком до тех пор, пока аварийная ситуация не будет сброшена обращением к методу TStream.Reset.
Прямой доступ к потокам
Поток имеет методы, имитирующие файловые процедуры прямого доступа к дисковому файлу.
С помощью функции GetPos программа может получить текущую позицию в потоке, т.е. номер байта, начиная с которого будет осуществляться очередная операция с потоком (первый байт потока имеет номер 0).
Метод Seek (Pos: LongInf) перемещает текущую позицию в потоке в байт Pos от начало потока.
Метод GetSize возвращает общий размер потока в байтах.
С помощью метода Truncate можно удалить из потока все данные, начиная с текущей позиции до конца потока.
Как видим, эти процедуры можно использовать только в том случае, если создать вне потока индексную коллекцию, содержащую начальные позиции в потоке для каждого из сохраняемых в нем объектов. Такая коллекция используется в ресурсах, поэтому для обеспечения прямого доступа к потоку лучше использовать файл ресурсов (см. гл.21).
Использование потоков с произвольными данными
Хотя потоки спроектированы в основном для работы с объектами, Вы можете использовать их для хранения не только полей объектов, но и любых других данных. При этом не следует обращаться к методам Put и Get, так как они предполагают доступ к объектам. Вместо этого Вы должны обратиться к низкоуровневым процедурам Write и Read.
Следующая простая программа использует поток для сохранения десяти случайных целых чисел:
Uses Objects; var S: TBufStream; {Экземпляр потока} k, j: Integer; begin WriteLn('Запись в поток:'); S.lnit('Test.dat', stCreate, 512); {Создаем поток} for k: = 1 to 10 do begin j: = Random(l00); {Получаем случайное целое} Write(j:8); {Выводим на экран} S.Write(j,2) {Помещаем в поток} end; Done; {Удаляем поток} S.lnit('Test.dat', stOpenRead, 512); WriteLn; WriteLn('Чтение из потока:'); for k: = 1 to 10 do begin S.Read(j,2); {Получаем целое из потока} Write (j:8) {Выводим на экран} end; S.Done; WriteLn end.
Для простоты в программу не включены средства контроля ошибок. В ходе прогона программы в текущем каталоге диска будет создан файл TEST.DАТ размером в 20 байт, а на экран будут выведены две строки с одинаковыми числами.