Курсова робота на тему: «ПОТОКИ»

ЗМІСТ

Вступ    3

1. Управління об’єктами в потоці    4

2. Читання і запис потоку    6

3. Методи Store і Load    8

4. Реєстрація об’єктів і записи реєстрації    11

5. Колекції в потоках і запис в потік    15

6. Екземпляри видимих піделементів    17

7. Прямий доступ до потоків і їх копіювання    19

8. Використання потоків з довільними даними    20

9. Обробка помилок    21

Висновки    22

Література    24

ВСТУП

Техніка об'єктно-орієнтованого програмування і Turbo Vision дають могутній спосіб інкапсуляції даних та кодів і могутні способи побудови взаємозв'язаних структур об'єкта. 
До останнього часу дані зберігалися в записах і запис на диск був простим, але дані усередині Turbo Vision в більшості випадків знаходяться усередині об'єктів. Звичайно, можна відокремити дані від об'єкта і записати їх на диск. Але оскільки сумісне зберігання даних і коду дає великі переваги, розділити їх знову було б кроком назад.
Чи не може Turbo Vision вирішити цю проблему?
Саме для цього розроблені потоки.
Потік Turbo Vision — це колекція об'єктів з визначеним способом зберігання: зазвичай у файлі, EMS, послідовному порту або деякому іншому пристрої. Потоки оробляють ведення/виведення на рівні об'єкту, а не на рівні даних. Коли ви розширюєте об'єкт Turbo Vision, необхідно забезпечити обробку всіх полів даних, які ви визначаєте.
Для того, щоб можна було виконувати введення/виведення, потрібно вказати компілятору який тип даних буде у файлі. Файл повинен бути типізованим і тип повинен бути визначений під час компіляції.
Turbo Pascal реалізує дуже корисне виключення з цього правила: доступ до нетипізованого файла через BlockWrite і BlockRead. Але обхід перевірки типів створює для програміста певні труднощі, хоча дозволяє йому виконувати дуже швидке двійкове введення/виведення.
Друга проблема в тому, що не можна використовувати файли з об'єктами. Turbo Pascal не дозволяє створити файл типу об'єкта. І оскільки об'єкти можуть містити віртуальні методи, адреса яких визначається під час виконання, збереження інформації VMT поза програмою не раціональне; читання такої інформації у програмі ще більш нераціональне.
Можна обійти цю проблему. Можна скопіювати дані об'єктів і зберегти цю інформацію у файлі, а потім ще раз побудувати об'єкти з цих даних. Але це не практичне рішення і воно ускладнює створення об'єктів.
Turbo Vision дозволяє обійти обидві проблеми, а також надає деякі додаткові можливості.
Потоки надають простий, надзвичайно практичний спосіб зберігання даних об'єкта поза програмою.
				

УПРАВЛІННЯ ОБ’ЄКТАМИ В ПОТОЦІ

Все, що потрібно зробити — це визначити для потоку, які об'єкти він повинен обробляти, щоб він знав як сумістити дані з VMT. Потім можна помістити об'єкти в потік і отримати їх назад без зусиль.
Але як можна читати і писати в один потік такі різні об'єкти як TDeskTop і TDiаlog і під час компіляції не знати навіть які об'єкти оброблятимуться? Це сильно відрізняється від введення/виведення традиційного Паскаля. Насправді потік може обробляти навіть нові типи об'єктів, які ще не були створені у момент компіляції потоку.
Це здійснюється за допомогою реєстрації. Кожному типу об'єкта Turbo Vision (і новим типам об'єктів, які ви породжуєте з ієрархії) призначається унікальний реєстраційний номер. Цей номер записується в потік перед даними об'єкта. Потім, коли ви читаєте об'єкт потоку, Turbo Vision бере реєстраційний номер і на його основі знає скільки даних прочитати і яку VMT під'єднати до ваших даних.
				
На фундаментальному рівні про потоки можна говорити як про файли Паскаля. У своїй основі файл Паскаля — це просто послідовний пристрій введення/виведення. У свою чергу потік — це поліморфний послідовний пристрій введення/виведення, що означає, що він поводиться так само, як послідовний файл, але можна так само читати і писати об'єкти різного типу.
Потоки можна також розглядати (як і файли Паскаля) як пристрій введення/виведення з прямим доступом, де ви встановлюєте позицію в файлі, читаєте або пишите з цієї точки, повертаєте позицію покажчика файла і т.д. 
Існує два аспекти використання потоку. Перший — це установка потоку, другий — читання і запис об'єктів в потік.
Для використання потоку ви  повинні просто ініціалізувати його. Точний синтаксис конструктора Init змінюватиметься залежно від типу використовуваного потоку. Наприклад, якщо ви відкриваєте потік DOS, вам потрібно передати ім'я файлу DOS і режим доступу (читання, запис, читання/запис) до файлу, що містить потік.
Щоб ініціалізувати цей потік, для завантаження об'єкту панель екрана в програму, вам потрібно тільки: 
var
SaveFile: TBufStream;
begin
SaveFile.Init('SAMPLE.DSK', stOpen, 1024);
Після того, як потік ініціалізований, його можна використовувати.
TStream — це абстрактний механізм потоку і ви не можете створити екземпляр від нього, але всі об'єкти потоків породжені від TStream. Вони включають TDosStream, що забезпечує дискове введення/виведення, TBufStream, що забезпечує буферизоване введення/виведення з диска і TEmsStream, який пересилає об'єкти в EMS пам'ять (особливо корисний для реалізації швидких ресурсів).
Turbo Vision так само реалізує індексовані потоки з покажчиком на місце в потоці. Змінюючи положення покажчика, ви можете здійснювати прямий доступ до потоку.

ЧИТАННЯ І ЗАПИС ПОТОКУ

Базовий об'єкт потоків TStream реалізує три основних методи: Get, Put і Error. Get і Put приблизно відповідають процедурам Read і Write. Процедура Error викликається при виникненні помилки в потоці.
Спочатку розглянемо процедуру Put. Загальний синтаксис методу Put має вигляд:
SomeStream.Put(PSomeObject);
де SomeStream — це будь-який об'єкт, ініціалізований і породжений від TStream, а PSomeObject — це покажчик на будь-який об'єкт, породжений від TObject і зареєстрований з цим потоком. Це все, що потрібно зробити. Потік може взнати VMT PsomeObject  тип об'єкту (припускаючи, що тип був зареєстрований) і, отже, знати, який номер ID записувати і скільки даних записати після нього.
Важливим є те, що коли ви записуєте в потік групу з піделементами, піделементи автоматично записуватимуться в потік. Тому збереження складного об'єкту буде зовсім не складним, оскільки виконується автоматично. Можна зберегти програму просто записавши панель екрану в потік. Коли знову запустити програму і завантажити панель екрану, програма буде в тому ж стані, що і в точці збереження панелі екрану.

Отже, щоб помістити об’єкт в потік, потрібно звернутися до методу Put, передавши йому як параметр ініційований екземпляр об’єкту. Наприклад:

var

MyStream: TBufStream;{Екземпляр потоку}

MyWindow: TMyWindow;{Екземпляр об’єкту}

…..

MyStream.Put(MyWindow);{Поміщаємо об’єкт в потік}

Заздалегідь об’єкт повинен бути зареєстрований зверненням до RegisterType, а потік — ініційований за допомогою TXXXStream.Init.

Метод Put спочатку відшукує об’єкт в реєстраційному списку, що створюється процедурою RegisterType, і отримує з цього списку реєстраційний номер об’єкту і адресу його методу Store. Потім в потік записується реєстраційний номер і викликається метод Store, який копіює в потік всі поля об’єкту.

Зчитувати об’єкти з потоку так само просто. Це робиться, використовуючи функцію Get:

PSomeObject := SomeStream.Get;
де як і раніше SomeStream — ініціалізований потік Turbo Vision, а РSomeObject — покажчик на будь-який тип об'єкта Turbo Vision. Get просто повертає покажчик на те, що він зчитав з потоку. Скільки даних він зчитав і який тип VMT він призначив цим даним визначається не типом PSomeObject, а типом об'єкта знайденого в потоці. Тому, якщо об'єкт в поточній позиції SomeStream не того ж типу, що PSomeObject, ви одержите випадкову інформацію.

Метод Get спочатку прочитує з потоку реєстраційний номер об’єкту, потім відшукує його в реєстраційному списку і викликає відповідний конструктор Load. Конструктор розміщує в динамічній пам’яті екземпляр прочитуваного об’єкту, а потім прочитує з потоку всі його поля. Результатом роботи Get є покажчик, що не типізується, на знову створений і ініційований об’єкт. Наприклад:

type

MyStream: TBufStream;{Екземпляр потоку}

PWindow: PMyWindow;{Покажчик на екземпляр об’єкту}

…..

PWindow:= MyStream.Get;{Отримуємо об’єкт з потоку}

Відмітимо, що кількість прочитуваних з потоку даних і тип ТВМ, який призначений знову створеному об’єкту, визначається не типом PWindow, а реєстраційним номером, отриманим з потоку. Можна помилково помістити в лівій частині оператора привласнення покажчика на об’єкт іншого типу і Turbo Vision не зможе попередити вас про це.

Як і Put, Get відновлює складні об'єкти. Так, якщо об'єкт, зчитаний вами з потоку, — це видимий елемент, що володіє піделементами, піделементи будуть так само завантажені.
Процедура Error визначає що відбудеться, коли виникне помилка. За замовчуванням TStreamError просто встановлює 2 поля (Status і ErrorInfo) в потоці. Якщо ви хочете виконати інші дії, наприклад згенерувати помилку часу виконання або вивести помилку в діалогове вікно, необхідно перекрити процедуру Error.
				
Коли ви закінчуєте використання потоку, ви викликаєте метод Done точно так, як і Close для дискового файлу. Як і для будь-якого об'єкту Turbo Vision потрібно ввести:
Dispose (SomeStream, Done);
який видаляє об'єкт потоку.

МЕТОДИ STORE І LOAD

Читання і запис об’єктів в потік обробляється методами Load і Store.

Метод Store здійснює запис даних в потік. Для цього він використовує метод низького рівня Write, передаючи йому як параметри ім’я записуваного поля і довжину поля в байтах. Відмітимо, що немає потреби записувати всі поля об’єкту: для запису успадкованих полів досить просто звернутися до методу Store об’єкту-батька. Метод Store повинен записувати тільки ті поля, які додаються до полів батька. Якщо, наприклад, створений об’єкт

type

TMyDialog = object (TDialog)

St: String;{Нове поле}

Procedure Store(var S: TStream); Virtual;

…..

end;

то метод TMyDialog.Store може мати таку реалізацію:

Procedure TMyDialog.Store(var S: TStream);

begin

TDialog.Store(S); {Зберігаємо успадковані поля}

SA.Write(St, SizeOf(St)); {Зберігаємо нове поле}

end;

Аналогічним чином реалізується і конструктор Load: за допомогою звернення до низькорівневого методу TStream.Read він отримує з потоку тільки додаткові поля і лише в тому порядку, як вони були записані в потік методом Store:

Constructor TMyDialog.Load(var S: TStream);

begin

TDialog.Load(S); {Отримуємо успадковані поля}

S.Read(St, SizeOf(St)); {Отримуємо нове поле}

end;

Потрібно ретельно стежити за відповідністю методів Store і Load. Метод Load повинен прочитати рівно стільки байт і строго в тій послідовності, скільки байт і в якій послідовності помістив в потік метод Store У Turbo Vision немає засобів контролю за правильністю прочитуваних даних.

Якщо об’єкт — група, слід включити в нього поля-покажчики на кожен з елементів і використовувати методи PutSubViewPtr і GetSubViewPtr відповідно для запису в потік і читання з нього. Наприклад:

type

TMyDialog = object (TDialog)

St: String; {Текстове поле}

PB: PButton; {Покажчик на кнопку}

Procedure Store(var S: TStream); Virtual;

Constructor Load(var S: TStream);

…..

end;

Procedure TMyDialog.Store(var S: TStream);

begin

TDialog.Store(S); {Зберігаємо успадковані поля}

S.write(ST, SizeOf(St)); {Зберігаємо текстове поле}

PutSubViewPtr(S, PB); {Зберігаємо кнопку}

end;

Constructor TMyDialog.Load(var S: TStream);

begin

TDialog.Load(S); {Отримуємо успадковані поля}

S.Read(St, SizeOf(St)); {Отримуємо тестове поле}

GetSubViewPtr(S, PB); {Отримуємо кнопку}

end;

Відмітимо, що PGraphPoint не вимагає методу Store, оскільки не додає полів при спадкоємстві від PGraphObject.
type
PGraphObject = ^TGraphObject;
TGraphObject = object(TObject);
.
procedure Store(var S: TStream); virtual;
end;
PGraphCircle = ^TGraphCircle;
TGraphCircle = object(TGraphObject)
Raduis: Integer;
.
procedure Store(var S: TStream); virtual;
end;
PGraphRect = ^TGraphRect;
TGraphRect = object(TGraphObject)
Width, Height: Integer;
.
procedure Store(var S: TStream); virtual;
end;
Реалізація Store проста. Кожен об'єкт викликає метод Store, який зберігає всі дані. Потім метод Write потоку записує додаткові дані.
TGraphObject не викликає TObject.Store, оскільки TObjeсt не має даних для збереження: 
procedure TGraphObject.Store (var S: TStream);
begin
S.Write (X, SizeOf(X));
S.Write (Y, SizeOf(Y));
end;
procedure TGraphCircle.Store (var S: TStream);
begin
TGraphObject.Store (S);
S.Write (Radius, SizeOf(Radius));
end;
procedure TGraphRect.Store (var S: TStream);
begin
TGraphObject.Store(S);
S.Write (Width, SizeOf(Width));
S.Write (Height, SizeOf(Height));
end;
Відмітимо, що метод Write із TStream виконує двійковий запис. Його перший параметр може бути змінною будь-якого типу, але TStream.Write не знає розміру цієї змінної. Другий параметр надає цю інформацію і потрібно використовувати стандартну функцію SizeOf. Таким чином, якщо треба змінити координатну систему, використовуючи числа з плаваючою крапкою, то не потрібно коректувати методи Store.

ЗАВАНТАЖИТИ

Для скачування файлів необхідно або Зареєструватись

Potoky (160.5 KiB, Завантажень: 1)

Сторінка: 1 2 3 4
завантаження...
WordPress: 23.27MB | MySQL:26 | 0,320sec