Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник Емельянов.doc
Скачиваний:
12
Добавлен:
03.11.2018
Размер:
3.25 Mб
Скачать

Потоки данных

Потоки - достаточно мощное средство при реализации операций ввода или вывода данных, располагающихся на различных носителях. Потоки представляют собой специальные объекты, которые строятся с помощью наследников абстрактного класса TStream. Этот класс содержит методы, в которых заложены операции чтения, записи, изменения текущего положения указателя данных, открытия и закрытия потока. Поскольку для разных носи-

170

телей реализация указанных выше операций зависит от конкретной реализа­ции устройства, построено несколько специальных классов. Наиболее часто используются потоки TFileStream, THandleStream для работы с файлами на диске и TMemoryStream для работы с памятью. TFileStream используется, когда необходимо работать с именем файла, THandleStream используется, например, с файлами Windows, когда определяется дескриптор файла.

Любая работа с файловым потоком начинается с его построения. При этом используется стандартный конструктор Create(const Filename:string; Mode:Word). Параметр Filename задает имя файла, а параметр Mode - ре­жимы создания (fmCreate), чтения (fmOpenRead), записи (fmOpenWrite) или одновременного чтения и записи (fmOpenReadWrite) файла. С помо­щью операции логического или (or) к указанному параметру можно доба­вить режим совместного использования, например fmShareExclusive - файл недоступен для открытия другими приложениями. При этом поток работает с файлом без учета типа хранящихся в нем данных.

Для чтения и записи данных при работе с потоком используются методы Read и Write, содержащие по два параметра: переменная, куда считываются байты и количество байтов.

ПРИМЕР ПРИЛОЖЕНИЯ 21

Пусть заданы некоторые совокупности целых чисел. Требуется постро­ить, используя эти данные, диаграммы (или графики). Данные берутся из файлов. С помощью, например, StringGrid можно вводить новые данные или корректировать значения точек и записывать в файлы. Работу с файлами необходимо реализовать с помощью потоков.

В данном примере нам понадобятся три новых компонента. Для визуа­лизации данных воспользуемся диаграммами, которые можно построить с помощью компонента TChart со страницы Additional палитры компонентов. Данный компонент имеет множество настроек и позволяет представлять од­новременно несколько диаграмм. В данном случае из множества настроек выберем минимум. Представляемые данные в виде серий задаются с помо­щью рядов целых чисел (Series). Для создания таких рядов необходимо по­сле размещения компонента на форме щелкнуть на нем правой кнопкой мы­ши. В появившемся выпадающем меню выбрать пункт Edit Chart - откроет­ся редактор с двумя вкладками. Щелкнуть мышкой на вкладке Chart. С по­мощью кнопки Add построим, например, три ряда (Series) точек и для каж­дого ряда выберем вариант графика, цвет и подпись. На форме появятся объ­екты типа TBarSeries. Далее на вкладке Series выбрать страницу Data Source и установить Random Values (для построения графиков с помощью случайных точек). Все свойства можно редактировать в инспекторе объек­тов.

171

Для демонстрации возможностей файловых потоков нам понадобятся два диалоговых стандартных компонента со страницы Dialogs: OpenDialog-выбор открываемого файла и SaveDialog - выбор сохраняемого файла. Ос­новная настройка этих элементов заключается в задании расширения выби­раемых файлов (DefaultExt - задать CHR - тип файлов, с которыми рабо­тает компонент TChart) и фильтра (Filter). Чтобы задать фильтр в файловых диалогах, из инспектора объектов необходимо выйти в FilterEditor и на­брать в каждом компоненте по-две строчки (табл. 15).

Таблииа 15

Filter Name

Filter

Chart files(*.chr)

*.ctr

Any files(*.*)

*.*

Для открытия диалога вызывается метод Execute, а при выходе возвра­щается имя файла в свойстве FileName.

Изменить ;| ■ Метки


Вариант решения примера 21 приводится на рис. 49.

Рис. 49

В примере используется ряд обработчиков событий. Обработчик Form-Create задает первоначальные значения для исходных данных, которые при необходимости можно записать в файл (кнопка "Запись", обработчик Save-ButtonClick) или проигнорировать, загрузив данные из файла (кнопка "Файл", обработчик OpenButtonClick). Кроме того, запоминаются в массиве 172

ge (объявлен в секции формы private) настройки цвета диаграмм и вызыва­ется обработчик (UpdateButtonClick, кнопка "Изменить"), который строит эти диаграммы. С помощью свернутых списков Combos запоминаются вари­анты графиков (или диаграмм). Использование обработчиков ComboChange и ChBoxMarksCIick позволяет выбрать соответственно желаемый вид диа­граммы или промаркировать их (при необходимости можно записать в файл свой выбор). Из всего многообразия графиков в данном случае выбраны че­тыре: линейный, столбиковый, поверхность, точки (занесены в списки ис­пользуемых трех элементов TComboBox). Для удобства коррекции данных в строковой таблице подключается маска ввода в виде обработчика StringGrid1GetEditMask. Ниже приводится текст программы.

unit Prim21; interface

uses SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls, TeEngine, Series, ExtCtrls, TeeProcs, Chart, Menus, Buttons; type

TForm1 = class(TForm)

Chartl: TChart;

Seriesl: TBarSeries;

Series2: TBarSeries;

Series3: TBarSeries;

Panel1: TPanel;

ChBoxMarks: TCheckBox;

OpdateButton: TButton;

StringGrid1: TStringGrid;

ComboBox1: TComboBox;

ComboBox2: TComboBox;

СотЬоВохЗ: TComboBox;

OpenDialog1: TOpenDialog;

SaveDialog1: TSaveDialog;

OpenButton: TButton;

SaveButton: TButton;

BitBtnl: TBitBtn;

procedure FormCreate(Sender: TObject);

procedure OpdateButtonClick(Sender: TObject);

procedure StringGrid1GetEditMask(Sender: TObject; ACol, ARow: Longint; var Value: string);

procedure ChBoxMarksCIick(Sender: TObject);

procedure ComboChange(Sender: TObject);

procedure OpenButtonClick(Sender: TObject);

procedure SaveButtonClick(Sender: TObject); private

Combos: array [ 0..2] of TComboBox;

CurrentFile: s tring;

Se:array [1..3] of TColor;

173

end;

var Form1: TForm1;

implementation

{$R *.DFM}

Procedure TForm1.FormCreate(Sender:TObject);

var I, J: Integer;

begin

with StringGrid1 do begin

for I:=l to 5 do Cells[I,0]:= Format('Группа %d', [I]);

for J:=l to 3 do Cells[0,J]:= Format('Серия %d', [J]); Randomize;

for I := 1 to 5 do

for J := 1 to 3 do

Cells [I,J] :=IntToStr(Random(100));

end;

Combos [0]:= ComboBox1;

Combos [1] := ComboBox2;

Combos [2] := СоmbоВохЗ;

for I := 0 to 2 do begin Combos[I].Itemlndex := 1; Se[I+l]:=Chartl.Series[I].SeriesColor; end;

UpdateButtonClick(self);

end;

procedure TForm1.OpdateButtonCliek(Sender: TObject); var I, J: Integer;

begin

for I := 1 to 3 do begin Chart1.Series[I-1].Clear;

for J:=1 to 5 do Chartl.Series [I-l].Add(

StrToInt(StringGrid1.Cells[J,I]), ' ', Se[I]); end; end;

Procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol, ARow: Longint; var Value: string); begin

Value:= ’09:0’; end;

procedure TForm1.ChBoxMarksClick(Sender: TObject);

var I: Integer;

begin

for I := 1 to 3 do

Chartl.Series[I-l].Marks.Visible:= ChBoxMarks.Checked; end;

procedure TForm1.ComboChange(Sender: TObject);

var I: Integer;

SeriesClass: TChartSeriesClass;

NewSeries: TChartSeries;

174

begin

for I := 2 downto 0 do Chartl.Series[I].Free;

for I := 0 to 2 do begin

case Combos [I].Itemlndex of

0: SeriesClass := TLineSeries; 1: SeriesClass := TBarSeries; 2: SeriesClass := TAreaSeries;

else SeriesClass := TPointSeries;

end;

NewSeries:=SeriesClass.Create(self); NewSeries.ParentChart := Chartl;

NewSeries.Title :=Format('Серия %d', [1+1]);

end;

ChBoxMarksClick(self); UpdateButtonClick(self); end;

procedure TForm1.OpenButtonClick(Sender: TObject);

var ReadStream: TFileStream;

I, J, Value: Integer; begin

if OpenDialog1.Execute then begin CurrentFile := OpenDialog1.Filename;

Caption :=' ПРИМЕР 20 (Данные файла '+ CurrentFile+')'; try

ReadStream:= TFileStream.Create(CurrentFile,fmOpenRead);

for I := 1 to 5 do

for J := 1 to 3 do begin

ReadStream.Read(Value, SizeOf(Integer)); StringGrid1.Cells[I, J] := IntToStr(Value);

end;

ReadStream.Read(Value, SizeOf(Integer)); ChBoxMarks.Checked := Boolean(Value);

for I := 0 to 2 do begin

ReadStream.Read(Value, SizeOf(Integer)); Combos[I].Itemlndex := Value; ReadStream.Read(Value, SizeOf(Integer)); Se[i+1] := Value;

end;

finally

ReadStream.Free; end;

ChBoxMarksClick(self) ; ComboChange(self ); UpdateButtonClick(self) ; end; end;

procedure TForm1.SaveButtonClick(Sender: TObject); var SaveStream: TFileStream;

175

177

I, J, Value: Integer; begin

if SaveDialog1.Execute then begin CurrentFile := SaveDialog1.Filename;

Caption :=' ПРИМЕР 20 (Данные файла ' + CurrentFile+')'; try Savestream := TFileStream.Create(CurrentFile,

fmOpenWrite or fmCreate); for I := 1 to 5 do

for J := 1 to 3 do begin Value := StrToIntDef(

Trim(StringGrid1.Cells[I, J]), 0) ; SaveStream.Write(Value,SizeOf(Integer)); end;

Value := Integer(ChBoxMarks.Checked); SaveStream.Write(Value,SizeOf(Integer)); for I := 0 to 2 do begin

Value := Combos [I].Itemlndex; SaveStream. Write(Value,SizeOf(Integer)); SaveStream.Write(Se[i+l],SizeOf(Integer)); end; finally

SaveStream.Free; end;

end;

end; .

end.

Работа с потоками реализована в обработчиках OpenButtonclick и SaveButtonClick, в которых соответственно выполняется чтение файла в поток Readstream и запись потока SaveStream в файл. Компонент TChart работает с собственным типом бинарных файлов. Потоки Readstream и SaveStream корректно записывают и воспроизводят информацию. В данном случае информация складывается из целых чисел в следующей последова­тельности: точки графиков, признак меток (преобразуется в булевый тип из числа), виды графиков и их цвета.