Отношения наследования TMemoryStream следующие:
ТОбъект
|
TStream
|
TCustomMemoryStream
|
TMemoryStream
Как использовать TMemoryStream?
Фактически, TmemoryStream используется так же, как и TStream.
Конкретные атрибуты и методы см. в справке.
Вот пример:
Что мне делать, если я хочу читать и записывать растровые изображения непосредственно в памяти?
TmemoryStream вам очень поможет
вар
BitmapMemoryStream:TMemoryStream;
Растровое изображение1:TBitmap;
PROcedure TForm.Button1Click(Sender:TObject);
начинать
BitmapmemroyStream:=TmemoryStream.Create file://Create MemoryStream;
Bitmap1:=TBitmap.Create;
пытаться
Bitmap1.LoadFromFile('d:Bitmap1.bmp');
кроме
ShowMessage('Ошибка при загрузке файла bitmap1.bmp');
конец;
конец;
процедура TForm.Button2Click(Sneder:Tobject);
начинать
если назначено (растровое изображение1), то
Bitmap1.SaveToStream(BitmapmemoryStream);
конец;
процедура TForm.Button3Click(Отправитель:TObject);
начинать
если BitmapMemoryStream<>nil, то
начинать
пытаться
BitmapMemroyStream.SaveToFile('Bitmap1.str'); file://сохранение потока памяти, размер и
файл://Bitmap1.bmp тот же
кроме
showmessage('ошибка доступа к памяти!');
конец;
конец;
конец;
процедура TForm.Button4Click(Отправитель:TObject);
вар
Буфер: Массив [0..53] символов;
начинать
если назначено (BitmapMemroyStream), то
пытаться
BitmapMemroyStream.Seek(0,soFromBeginning);
BitmapMemoryStream.Read(Буфер,54);
если Buffer[0]='B' и Buffer[1]='M', то file://перезаписывает содержимое памяти
начинать
BitmapMemoryStream.Seek(0,soFromBeginning);
BitmapmemoryStream.Write('ICE',3);
Button3Click(Sender);//Записываем переписанное содержимое в файл
конец;
кроме
ShowMessage('ошибка при доступе к memroyStream');
конец;
конец;
Вы можете увидеть, насколько удобно использовать TMemoryStream для чтения и записи памяти. Конечно, предварительно создавать Bitmap не нужно.
Вы можете использовать LoadFromFile для прямой загрузки файла, но для других потоков памяти вы можете использовать описанный выше метод.
Вышеуказанное является лишь введением. Что касается других функций, вы можете прочитать справку и разобраться в них самостоятельно!
Существует множество других потоковых объектов, все они практически одинаковы, поэтому вы можете использовать их все!
Как записать содержимое потока в буфер обмена и обработать
Этот метод реализуется со ссылкой на реализацию класса буфера обмена Delphi. Поместите содержимое потока в буфер обмена,
Сначала зарегистрируйте свой собственный формат с помощью функции RegisterClipboardFormat().
Затем выполните следующие три шага:
1. Создайте поток контента и запишите в него контент.
2. Создайте глобальную область контента и напишите содержимое потока.
3. Вызовите ClipBoard.SetAsHandle(), чтобы записать содержимое в буфер обмена.
Запись содержимого в буфер обмена
вар
hbuf :THandle;
buffptr: Указатель;
мстрим: TMemoryStream;
начинать
mstream:= TMemoryStream.Create;
пытаться
{-- Код обработки потоков --}
hbuf:= GlobalAlloc(GMEM_MOVEABLE, mstream.size);
пытаться
bufptr:= GlobalLock(hbuf);
пытаться
Move(mstream.Memory^, bufptr^, mstream.size);
Clipboard.SetAsHandle(CF_MYFORMAT, hbuf);
окончательно
Глобальная разблокировка (hbuf);
конец;
кроме
GlobalFree(hbuf);
поднимать;
конец;
окончательно
mstream.Бесплатно;
конец;
конец;
Будьте осторожны, чтобы не освободить выделенный глобальный буфер. Эта работа выполняется буфером обмена при чтении данных.
Вам следует скопировать его и обработать позже.
Прочитать содержимое буфера обмена
вар
hbuf :THandle;
buffptr: Указатель;
мстрим: TMemoryStream;
начинать
hbuf := Clipboard.GetAsHandle(CF_MYFORMAT);
если hbuf <> 0, то начнем
bufptr:= GlobalLock(hbuf);
если bufptr <> nil, то начать
пытаться
mstream:= TMemoryStream.Create;
пытаться
mstream.WriteBuffer(bufptr^, GlobalSize(hbuf));
mstream.Position:= 0;
{-- Код обработки потоков --}
окончательно
mstream.Бесплатно;
конец;
окончательно
Глобальная разблокировка (hbuf);
конец;
конец;
конец;
конец;
Советы по использованию TStream для чтения и записи данных в Dephi
В Dephi предусмотрен абстрактный тип данных TStream для поддержки операций с потоковыми данными. Эти данные обычно поступают из файлов, баз данных, объектов памяти, объектов OLE и т. д. TStream предоставляет унифицированный и лаконичный метод чтения и записи данных. В обычных обстоятельствах нам не нужно напрямую использовать класс TStream, а чтение и запись потоковых данных инкапсулируются в методах элемента управления VCL. Но если эти методы не могут удовлетворить наши требования, нам нужно самим вручную контролировать чтение и запись данных.
1. Часто используемые методы и свойства TStream:
---- 1. функция Read(var Buffer; Count: Longint): Longint virtual;
---- 2. функция Write(const Buffer; Count: Longint): Longint virtual;
---- 3. функция Seek(Смещение: Longint; Origin: Word): Longint virtual;
---- 4. Позиция свойства: Longint;
---- 5. Размер свойства: Longint
---- Чтение, запись и поиск — это чисто виртуальные функции, предоставляющие абстрактные методы для чтения, записи и позиционирования данных. Метод Read считывает данные из потока в буфер, а метод Write реализует противоположную операцию. Возвращаемое значение указывает фактический размер считанных и записанных данных. Seek предоставляет метод для перемещения указателя данных в потоке. Параметр Origin может принимать три значения: soFromBeginning, soFromCurrent и soFromEnd. Offset — это смещение, а возвращаемое значение — это позиция текущего указателя данных Stream.
---- Position представляет положение указателя данных в потоке. Это свойство доступно для чтения и записи. Фактически оно реализуется путем вызова метода Seek, поэтому его удобнее использовать в реальных условиях. Атрибут Size указывает размер текущего потока. Для разных потоков он иногда доступен только для чтения.
2. Чтение и запись данных потока.
---- 1. SaveToStream(Stream: TStream); file:// записывает данные в класс в текущую позицию потока.
---- 2. LoadFromStream(Stream: TStream); file://Читать данные в потоке с текущей позиции.
---- При реальном использовании нам в основном нужно использовать только две вышеуказанные функции.
3. Примеры
----Диаграмма дерева наследования TStream показана на рисунке 1 (опущена). В реальном использовании чаще используются TFileStream, TMemoryStream и TblobStream. Давайте рассмотрим эти три потока в качестве примера, чтобы проиллюстрировать конкретное использование.
---- Создайте форму Form1, разместите три кнопки btnRead, btnInvert, btnSave и диалоговое окно открытия файла OpenDialog1, а также элементы управления данными DataSource1, Table1, test.
---- Используйте рабочий стол базы данных, предоставленный Dephi, для создания теста таблицы. В таблице есть поле Image, а имя файла базы данных сохраняется как test.db. Поместите в форму элемент управления TDatabase dbTest, элемент управления TTable Table1, элемент управления DataSource DataSource1 и элемент управления TDBNavigator DBNavigator1. Подключите dbTest к базе данных, только что созданной Desktop, задайте для свойства TableName объекта Table1 значение test.db, задайте для свойства DataSet объекта DataSource1 значение Table1, задайте для свойства DataSource объекта DBNavigator1 значение DataSource1 и установите для первых четырех свойств VisibleButtons значение TRUE. Кроме того, установите для свойства Connected dbtest значение TRUE, а для свойства Active таблицы Table1 — значение TRUE, чтобы база данных была открыта с самого начала.
----Код события записывается следующим образом:
---- 1. Щелкните событие btnRead, здесь демонстрируется использование TFileStream.
вар
MS: TFileStream;
начинать
если OpenDialog1.Execute, то
начинать
MS:=TFileStream.Create
(OpenDialog1.FileName, fmOpenRead);
Изображение1.Картинка.Растровое изображение.LoadFromStream(MS);
MS.Бесплатно;
конец;
конец;
---- 2. Событие щелчка btnInvert, здесь демонстрируется использование TMemoryStream. Используется функция Invert, которая представляет собой простую функцию, которая инвертирует цвет изображения (действительна только для изображений с настоящими цветами). Она возвращает указатель на обработанный блок данных изображения.
вар
М
СУБЪЕКТ: TMemoryStream;
pImage: указатель;
начинать
MS:=TMemoryStream.create;
Изображение1.Картинка.Растровое изображение.СохранитьToStream(MS);
MS.Позиция:=0;
pImage:=Invert(MS.Memory, MS.size);
Атрибут file://Memory является указателем на фактический блок памяти.
MS.Write(pImage^,MS.size);
MS.Позиция:=0;
Предыдущая строка кода в файле:// перемещает указатель в конец потока, поэтому его необходимо сбросить.
Изображение1.Картинка.Растровое изображение.LoadFromStream(MS);
FreeMem(pImage);
MS.Бесплатно;
конец;
Функция инвертирования выглядит следующим образом:
функция TForm1.Invert
(pImage: указатель; размер: целое число): указатель;
вар
pData, pMem: PChar;
я: целое число;
начинать
pMem:=AllocMem(размер);
CopyMemory(pMem,pImage,size);
pData:=pMem+54;
для i:=0 до размера-54-1 сделать
начинать
pData^:=Char(не целое число(pData^));
pДанные:=pДанные+1;
конец;
Результат:=pMem;
конец;
---- 1. Событие щелчка btnSave, здесь демонстрируется другое использование TMemoryStream, записывающее данные из потока в базу данных.
вар
MS: TMemoryStream;
начинать
MS:=TMemoryStream.create;
Изображение1.Картинка.Растровое изображение.СохранитьToStream(MS);
MS.Позиция:=0;
Таблица1.Добавить;
file://добавляет запись в базу данных
TBlobField(Таблица1.FieldbyName
('изображение')).LoadFromStream(MS);
Таблица1.Пост;
file:// записывает обновления в базу данных
конец;
---- 4. Событие щелчка DBNavigator1, здесь демонстрируется использование TBlobStream с использованием метода, отличного от записи, для чтения данных изображения из базы данных.
вар
МС: ТСтрим;
начинать
с Таблицей1 сделать
MS:=CreateBlobStream
(FieldbyName('изображение'),bmRead);
Изображение1.Картинка.Растровое изображение.
ЗагрузитьИзПотока(МС);
MS.Бесплатно;
конец;
Вот и все. Спасибо, что прочитали эту статью. У меня недостаточно баллов для использования, поэтому мне нужно заработать несколько баллов, чтобы их обменять. Если вы считаете, что эта статья полезна для вас, пожалуйста, проголосуйте за меня, спасибо.