The inheritance relationship of TMemoryStream is as follows
TObject
|
TStream
|
TCustomMemoryStream
|
TMemoryStream
How to use TMemoryStream?
In fact, TmemoryStream is used just like TStream.
For specific attributes and methods, please see the help.
Here's an example:
What should I do if I want to read and write a Bitmap directly in memory?
TmemoryStream helps you a lot
var
BitmapMemoryStream:TMemoryStream;
Bitmap1:TBitmap;
PRocedure TForm.Button1Click(Sender:TObject);
begin
BitmapmemroyStream:=TmemoryStream.Create; file://Create MemoryStream
Bitmap1:=TBitmap.Create;
try
Bitmap1.LoadFromFile('d:Bitmap1.bmp');
except
ShowMessage('Error On LoadFile bitmap1.bmp');
end;
end;
procedure TForm.Button2Click(Sneder:Tobject);
begin
if Assigned(Bitmap1) then
Bitmap1.SaveToStream(BitmapmemoryStream);
end;
procedure TForm.Button3Click(Sender:TObject);
begin
if BitmapMemoryStream<>nil then
begin
try
BitmapMemroyStream.SaveToFile('Bitmap1.str'); file://memory stream save, size and
file://Bitmap1.bmp same
except
showmessage('error on access memory!');
end;
end;
end;
procedure TForm.Button4Click(Sender:TObject);
var
Buffer:Array[0..53] of char;
begin
if Assigned(BitmapMemroyStream) then
try
BitmapMemroyStream.Seek(0,soFromBeginning);
BitmapMemoryStream.Read(Buffer,54);
if Buffer[0]='B' and Buffer[1]='M' then file://rewrite memory content
begin
BitmapMemoryStream.Seek(0,soFromBeginning);
BitmapmemoryStream.Write('ICE',3);
Button3Click(Sender);//Write the rewritten content to the file
end;
except
ShowMessage('error On Access memroyStream');
end;
end;
You can see how convenient it is to use TMemoryStream to read and write memory. Of course, there is no need to build a Bitmap first.
You can use LoadFromFile to directly boot the file, but for other memory streams, you can use the above method.
The above is just an introduction. For other functions, you can read the help and figure them out for yourself!
There are many other streaming objects, all of which are pretty much the same, so you can use them all!
How to write the contents of a stream to the clipboard and process
This technique is accomplished with reference to the implementation of Delphi's clipboard class. Put the contents of a stream into the clipboard,
First, register your own format using the RegisterClipboardFormat() function
Then do the following three steps:
1. Create a content stream and write the content into it
2. Create a global content area and write the content of the stream
3. Call ClipBoard.SetAsHandle() to write the content to the clipboard
Write content to clipboard
var
hbuf :THandle;
bufptr : Pointer;
mstream: TMemoryStream;
begin
mstream := TMemoryStream.Create;
try
{-- Code for processing streams --}
hbuf := GlobalAlloc(GMEM_MOVEABLE, mstream.size);
try
bufptr := GlobalLock(hbuf);
try
Move(mstream.Memory^, bufptr^, mstream.size);
Clipboard.SetAsHandle(CF_MYFORMAT, hbuf);
finally
GlobalUnlock(hbuf);
end;
except
GlobalFree(hbuf);
raise;
end;
finally
mstream.Free;
end;
end;
Please be careful not to release the allocated global buffer. This work is done by the clipboard. When reading the data
You should copy it and process it later.
Read the contents of the clipboard
var
hbuf :THandle;
bufptr : Pointer;
mstream: TMemoryStream;
begin
hbuf := Clipboard.GetAsHandle(CF_MYFORMAT);
if hbuf <> 0 then begin
bufptr := GlobalLock(hbuf);
if bufptr <> nil then begin
try
mstream := TMemoryStream.Create;
try
mstream.WriteBuffer(bufptr^, GlobalSize(hbuf));
mstream.Position := 0;
{-- Code for processing streams --}
finally
mstream.Free;
end;
finally
GlobalUnlock(hbuf);
end;
end;
end;
end;
Tips for using TStream to read and write data in Dephi
An abstract data type TStream is provided in Dephi to support operations on streaming data. These data usually come from files, databases, memory objects, OLE objects, etc. TStream provides a unified and concise method to read and write data. Under normal circumstances, we do not need to use the TStream class directly, and the reading and writing of streaming data are encapsulated in the methods of the VCL control. But if these methods cannot meet our requirements, we need to manually control the reading and writing of data ourselves.
1. Commonly used methods and properties of TStream:
---- 1. function Read(var Buffer; Count: Longint): Longint; virtual; abstract
---- 2. function Write(const Buffer; Count: Longint): Longint; virtual; abstract;
---- 3. function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;
---- 4. Property Position: Longint;
---- 5. Property Size: Longint
---- Read, Write, and Seek are all pure virtual functions, providing abstract methods for data reading, writing, and positioning. The Read method reads the data from the Stream into the Buffer, and the Write method implements the opposite operation. The return value indicates the actual size of the data read and written. Seek provides a method to move the data pointer in the Stream. The parameter Origin can take three values: soFromBeginning, soFromCurrent, and soFromEnd. Offset is the offset, and the return value is the position of the current Stream data pointer.
---- Position represents the position of the data pointer in the Stream. This property is readable and writable. It is actually implemented by calling the Seek method, so it is more convenient to use this property in actual use. The Size attribute indicates the size of the current Stream. For different Streams, it is sometimes read-only.
2. Reading and writing of Stream data.
---- 1. SaveToStream(Stream: TStream); file://writes the data in the class to the current position of the Stream
---- 2. LoadFromStream(Stream: TStream); file://Read the data in Stream from the current position
---- In actual use, we basically only need to use the above two functions.
3. Examples
----The inheritance tree diagram of TStream is shown in Figure 1 (omitted). In actual use, the more commonly used ones are TFileStream, TMemoryStream, and TblobStream. Let's take these three streams as an example to illustrate the specific usage.
---- Create a form Form1, place three buttons btnRead, btnInvert, btnSave and a file opening dialog box OpenDialog1 as well as data controls DataSource1, Table1, test.
---- Use the Database Desktop provided by Dephi to create a table test. There is a field Image in the table, and the database file name is saved as test.db. Place a TDatabase control dbTest, a TTable control Table1, a DataSource control DataSource1, and a TDBNavigator control DBNavigator1 on the form. Connect dbTest to the database just created by Desktop, set the TableName property of Table1 to test.db, set the DataSet property of DataSource1 to Table1, set the DataSource property of DBNavigator1 to DataSource1, and set the first four VisibleButtons properties to TRUE. In addition, set the Connected of dbtest to TRUE and the Active property of Table1 to TRUE so that the database is open from the beginning.
----The event code is written as follows:
---- 1. Click event of btnRead, here demonstrates the usage of TFileStream.
var
MS: TFileStream;
begin
if OpenDialog1.Execute then
begin
MS:=TFileStream.Create
(OpenDialog1.FileName, fmOpenRead);
Image1.Picture.Bitmap.LoadFromStream(MS);
MS.Free;
end;
end;
---- 2. Click event of btnInvert, here demonstrates the usage of TMemoryStream. The Invert function is used, which is a simple function that inverts the color of an image (only valid for true color images). It returns a pointer to the processed image data block.
var
M
S: TMemoryStream;
pImage: pointer;
begin
MS:=TMemoryStream.create;
Image1.Picture.Bitmap.SaveToStream(MS);
MS.Position:=0;
pImage:=Invert(MS.Memory, MS.size);
The file://Memory attribute is a pointer to the actual memory block
MS.Write(pImage^,MS.size);
MS.Position:=0;
The previous line of code in file:// moves the pointer to the end of the Stream, so it needs to be reset.
Image1.Picture.Bitmap.LoadFromStream(MS);
FreeMem(pImage);
MS.Free;
end;
The Invert function is as follows:
function TForm1.Invert
(pImage: pointer; size: Integer): pointer;
var
pData, pMem: PChar;
i: Integer;
begin
pMem:=AllocMem(size);
CopyMemory(pMem,pImage,size);
pData:=pMem+54;
for i:=0 to size-54-1 do
begin
pData^:=Char(not integer(pData^));
pData:=pData+1;
end;
Result:=pMem;
end;
---- 1. Click event of btnSave, here demonstrates another usage of TMemoryStream, writing the data in the Stream to the database.
var
MS: TMemoryStream;
begin
MS:=TMemoryStream.create;
Image1.Picture.Bitmap.SaveToStream(MS);
MS.Position:=0;
Table1.Append;
file://adds a record in the database
TBlobField(Table1.FieldbyName
('image')).LoadFromStream(MS);
Table1.Post;
file://writes the updates to the database
end;
---- 4. Click event of DBNavigator1, here demonstrates the usage of TBlobStream, using a different method from writing to read the image data of the database.
var
MS: TStream;
begin
with Table1 do
MS:=CreateBlobStream
(FieldbyName('image'),bmRead);
Image1.Picture.Bitmap.
LoadFromStream(MS);
MS.Free;
end;
That’s it. Thank you for reading this article. I don't have enough points to use, so I have to earn some points to redeem them. If you feel this article is helpful to you, please vote for me, thank you.