ความสัมพันธ์การสืบทอดของ TMemoryStream เป็นดังนี้
ถึงวัตถุ
-
ทีสตรีม
-
TCustomMemoryStream
-
TMemoryStream
วิธีการใช้งาน TMemoryStream
ในความเป็นจริง TmemoryStream นั้นใช้เหมือนกับ TStream
สำหรับแอตทริบิวต์และวิธีการเฉพาะ โปรดดูวิธีใช้
นี่คือตัวอย่าง:
ฉันควรทำอย่างไรหากต้องการอ่านและเขียนบิตแมปลงในหน่วยความจำโดยตรง
TmemoryStream ช่วยคุณได้มาก
var
BitmapMemoryStream:TMemoryStream;
บิตแมป1:TBitmap;
ขั้นตอน TForm.Button1Click (ผู้ส่ง: TObject);
เริ่ม
BitmapmemroyStream:=TmemoryStream.Create; file://Create MemoryStream
Bitmap1:=TBitmap.Create;
พยายาม
Bitmap1.LoadFromFile('d:Bitmap1.bmp');
ยกเว้น
ShowMessage('ข้อผิดพลาดในการ LoadFile bitmap1.bmp');
จบ;
จบ;
ขั้นตอน TForm.Button2Click (Sneder: Tobject);
เริ่ม
ถ้าได้รับมอบหมาย (Bitmap1) แล้ว
Bitmap1.SaveToStream(BitmapmemoryStream);
จบ;
ขั้นตอน TForm.Button3Click (ผู้ส่ง: TObject);
เริ่ม
ถ้า BitmapMemoryStream<>ไม่มีเลย
เริ่ม
พยายาม
BitmapMemroyStream.SaveToFile('Bitmap1.str'); file://memory stream บันทึก ขนาด และ
ไฟล์://Bitmap1.bmp เหมือนกัน
ยกเว้น
showmessage('ข้อผิดพลาดในการเข้าถึงหน่วยความจำ!');
จบ;
จบ;
จบ;
ขั้นตอน TForm.Button4Click (Sender: TObject);
var
บัฟเฟอร์: อาร์เรย์ [0..53] ของถ่าน;
เริ่ม
ถ้าได้รับมอบหมาย (BitmapMemroyStream) แล้ว
พยายาม
BitmapMemroyStream.Seek (0 ดังนั้นจากจุดเริ่มต้น);
BitmapMemoryStream.Read(บัฟเฟอร์,54);
ถ้า Buffer[0]='B' และ Buffer[1]='M' ให้ file://rewrite เนื้อหาหน่วยความจำ
เริ่ม
BitmapMemoryStream.Seek (0 ดังนั้นจากจุดเริ่มต้น);
BitmapmemoryStream.Write('ICE',3);
Button3Click(Sender);//เขียนเนื้อหาที่เขียนใหม่ลงในไฟล์
จบ;
ยกเว้น
ShowMessage('ข้อผิดพลาดในการเข้าถึง memroyStream');
จบ;
จบ;
คุณสามารถดูได้ว่าการใช้ TMemoryStream เพื่ออ่านและเขียนหน่วยความจำนั้นสะดวกเพียงใด แน่นอนว่าไม่จำเป็นต้องสร้างบิตแมปก่อน
คุณสามารถใช้ LoadFromFile เพื่อบูตไฟล์ได้โดยตรง แต่สำหรับสตรีมหน่วยความจำอื่น คุณสามารถใช้วิธีการข้างต้นได้
ข้างต้นเป็นเพียงการแนะนำเท่านั้น สำหรับฟังก์ชันอื่นๆ คุณสามารถอ่านวิธีใช้และคิดออกเองได้!
มีออบเจ็กต์การสตรีมอื่น ๆ อีกมากมาย ซึ่งทั้งหมดค่อนข้างจะเหมือนกัน ดังนั้นคุณสามารถใช้มันทั้งหมดได้!
วิธีเขียนเนื้อหาของสตรีมไปยังคลิปบอร์ดและดำเนินการ
เทคนิคนี้สำเร็จได้โดยอ้างอิงถึงการใช้งานคลาสคลิปบอร์ดของ Delphi ใส่เนื้อหาของสตรีมลงในคลิปบอร์ด
ขั้นแรก ให้ลงทะเบียนรูปแบบของคุณเองโดยใช้ฟังก์ชัน RegisterClipboardFormat()
จากนั้นทำสามขั้นตอนต่อไปนี้:
1. สร้างสตรีมเนื้อหาและเขียนเนื้อหาลงไป
2. สร้างพื้นที่เนื้อหาส่วนกลางและเขียนเนื้อหาของสตรีม
3. เรียก ClipBoard.SetAsHandle() เพื่อเขียนเนื้อหาไปยังคลิปบอร์ด
เขียนเนื้อหาลงในคลิปบอร์ด
var
hbuf :THandle;
bufptr : ตัวชี้;
mstream: TMemoryStream;
เริ่ม
mstream := TMemoryStream.Create;
พยายาม
{-- รหัสสำหรับการประมวลผลสตรีม --}
hbuf := GlobalAlloc(GMEM_MOVEABLE, mstream.size);
พยายาม
bufptr := GlobalLock(hbuf);
พยายาม
ย้าย(mstream.Memory^, bufptr^, mstream.size);
คลิปบอร์ด SetAsHandle (CF_MYFORMAT, hbuf);
ในที่สุด
GlobalUnlock(hbuf);
จบ;
ยกเว้น
GlobalFree(hbuf);
ยก;
จบ;
ในที่สุด
mstream.ฟรี;
จบ;
จบ;
โปรดระวังอย่าปล่อยบัฟเฟอร์ส่วนกลางที่จัดสรรไว้ งานนี้จะดำเนินการโดยคลิปบอร์ด
คุณควรคัดลอกและดำเนินการในภายหลัง
อ่านเนื้อหาของคลิปบอร์ด
var
hbuf :THandle;
bufptr : ตัวชี้;
mstream: TMemoryStream;
เริ่ม
hbuf := คลิปบอร์ด.GetAsHandle(CF_MYFORMAT);
ถ้า hbuf <> 0 ให้เริ่ม
bufptr := GlobalLock(hbuf);
ถ้า bufptr <> ไม่มี ให้เริ่มต้น
พยายาม
mstream := TMemoryStream.Create;
พยายาม
mstream.WriteBuffer(bufptr^, GlobalSize(hbuf));
mstream ตำแหน่ง := 0;
{-- รหัสสำหรับการประมวลผลสตรีม --}
ในที่สุด
mstream.ฟรี;
จบ;
ในที่สุด
GlobalUnlock(hbuf);
จบ;
จบ;
จบ;
จบ;
เคล็ดลับการใช้ TStream เพื่ออ่านและเขียนข้อมูลใน Dephi
TStream ประเภทข้อมูลนามธรรมมีให้ใน Dephi เพื่อรองรับการดำเนินการกับข้อมูลสตรีมมิ่ง ข้อมูลเหล่านี้มักมาจากไฟล์ ฐานข้อมูล ออบเจ็กต์หน่วยความจำ ออบเจ็กต์ OLE ฯลฯ TStream ให้วิธีการอ่านและเขียนข้อมูลแบบครบวงจรและกระชับ ภายใต้สถานการณ์ปกติ เราไม่จำเป็นต้องใช้คลาส TStream โดยตรง และการอ่านและการเขียนข้อมูลสตรีมมิ่งจะถูกห่อหุ้มไว้ในวิธีการของการควบคุม VCL แต่หากวิธีการเหล่านี้ไม่สามารถตอบสนองความต้องการของเราได้ เราจำเป็นต้องควบคุมการอ่านและการเขียนข้อมูลด้วยตนเอง
1. วิธีการและคุณสมบัติของ TStream ที่ใช้กันทั่วไป:
---- 1. ฟังก์ชั่น Read(var Buffer; Count: Longint): Longint; virtual
---- 2. ฟังก์ชั่นเขียน (const Buffer; Count: Longint): Longint; abstract;
---- 3. ฟังก์ชั่น Seek (Offset: Longint; Origin: Word): Longint; virtual;
---- 4. ตำแหน่งทรัพย์สิน: Longint;
---- 5. ขนาดทรัพย์สิน: Longint
---- การอ่าน เขียน และค้นหาล้วนเป็นฟังก์ชันเสมือนล้วนๆ ที่ให้วิธีการเชิงนามธรรมสำหรับการอ่าน การเขียน และการวางตำแหน่งข้อมูล วิธีการอ่านจะอ่านข้อมูลจากกระแสข้อมูลลงในบัฟเฟอร์ และวิธีการเขียนจะใช้การดำเนินการตรงกันข้าม ค่าที่ส่งคืนจะระบุขนาดที่แท้จริงของข้อมูลที่อ่านและเขียน Seek จัดเตรียมวิธีการย้ายตัวชี้ข้อมูลในสตรีม พารามิเตอร์ Origin สามารถใช้ค่าได้สามค่า: soFromBeginning, soFromCurrent และ soFromEnd Offset คือออฟเซ็ต และค่าที่ส่งคืนคือตำแหน่งของตัวชี้ข้อมูลสตรีมปัจจุบัน
---- ตำแหน่ง หมายถึงตำแหน่งของตัวชี้ข้อมูลในสตรีม คุณสมบัตินี้สามารถอ่านและเขียนได้จริง โดยเรียกใช้เมธอด Seek ดังนั้นจึงสะดวกกว่าในการใช้คุณสมบัตินี้ในการใช้งานจริง แอตทริบิวต์ Size ระบุขนาดของสตรีมปัจจุบัน สำหรับสตรีมต่างๆ บางครั้งจะเป็นแบบอ่านอย่างเดียว
2. การอ่านและการเขียนข้อมูลสตรีม
---- 1. SaveToStream(Stream: TStream); file://write ข้อมูลในคลาสไปยังตำแหน่งปัจจุบันของ Stream
---- 2. LoadFromStream(Stream: TStream); file://Read the data in Stream from the current position
---- ในการใช้งานจริงเราจำเป็นต้องใช้เพียงสองฟังก์ชันข้างต้นเท่านั้น
3. ตัวอย่าง
----แผนผังแผนผังมรดกของ TStream แสดงในรูปที่ 1 (ละเว้น) ในการใช้งานจริง TFileStream, TMemoryStream และ TblobStream ถูกใช้กันทั่วไปมากกว่า
---- สร้างแบบฟอร์ม Form1 วางปุ่มสามปุ่ม btnRead, btnInvert, btnSave และกล่องโต้ตอบการเปิดไฟล์ OpenDialog1 รวมถึงตัวควบคุมข้อมูล DataSource1, Table1, ทดสอบ
---- ใช้ฐานข้อมูลเดสก์ท็อปที่ Dephi จัดทำขึ้นเพื่อสร้างการทดสอบตาราง มีรูปภาพของฟิลด์ในตารางและชื่อไฟล์ฐานข้อมูลจะถูกบันทึกเป็น test.db วางตัวควบคุม TDatabase dbTest, ตัวควบคุม TTable Table1, ตัวควบคุมแหล่งข้อมูล DataSource1 และตัวควบคุม TDBNavigator DBNavigator1 บนแบบฟอร์ม เชื่อมต่อ dbTest กับฐานข้อมูลที่เพิ่งสร้างโดย Desktop ตั้งค่าคุณสมบัติ TableName ของ Table1 เป็น test.db ตั้งค่าคุณสมบัติ DataSet ของ DataSource1 เป็น Table1 ตั้งค่าคุณสมบัติ DataSource ของ DBNavigator1 เป็น DataSource1 และตั้งค่าคุณสมบัติ VisibleButtons สี่ตัวแรกเป็น TRUE นอกจากนี้ ให้ตั้งค่าการเชื่อมต่อของ dbtest เป็น TRUE และคุณสมบัติ Active ของ Table1 เป็น TRUE เพื่อให้ฐานข้อมูลเปิดตั้งแต่ต้น
----โค้ดเหตุการณ์เขียนดังนี้:
---- 1. คลิกเหตุการณ์ btnRead ที่นี่สาธิตการใช้งาน TFileStream
var
MS: TFileStream;
เริ่ม
ถ้า OpenDialog1.Execute แล้ว
เริ่ม
MS:=TFileStream.สร้าง
(OpenDialog1.FileName, fmOpenRead);
Image1.Picture.Bitmap.LoadFromStream (MS);
MS.ฟรี;
จบ;
จบ;
---- 2. คลิกเหตุการณ์ของ btnInvert ที่นี่สาธิตการใช้ TMemoryStream มีการใช้ฟังก์ชัน Invert ซึ่งเป็นฟังก์ชันง่ายๆ ที่จะกลับสีของรูปภาพ (ใช้ได้กับรูปภาพที่มีสีจริงเท่านั้น) โดยจะส่งคืนตัวชี้ไปยังบล็อกข้อมูลรูปภาพที่ประมวลผล
var
ม
S: TMemoryStream;
pImage: ตัวชี้;
เริ่ม
MS:=TMemoryStream.create;
Image1.Picture.Bitmap.SaveToStream (MS);
MS.ตำแหน่ง:=0;
pImage:=กลับด้าน(MS.Memory, MS.size);
แอตทริบิวต์ file://Memory เป็นตัวชี้ไปยังบล็อกหน่วยความจำจริง
MS.เขียน(pImage^,MS.size);
MS.ตำแหน่ง:=0;
บรรทัดโค้ดก่อนหน้าใน file:// ย้ายตัวชี้ไปที่ส่วนท้ายของ Stream ดังนั้นจึงจำเป็นต้องรีเซ็ต
Image1.Picture.Bitmap.LoadFromStream (MS);
FreeMem(pImage);
MS.ฟรี;
จบ;
ฟังก์ชันกลับด้านมีดังนี้:
ฟังก์ชั่น TForm1.Invert
(pImage: ตัวชี้; ขนาด: จำนวนเต็ม): ตัวชี้;
var
pData, pMem: PChar;
ฉัน: จำนวนเต็ม;
เริ่ม
pMem:=AllocMem(ขนาด);
CopyMemory(pMem,pImage,ขนาด);
ข้อมูล:=pMem+54;
สำหรับ i:=0 ถึงขนาด-54-1 ทำ
เริ่ม
pData^:=Char(ไม่ใช่จำนวนเต็ม(pData^));
pData:=pData+1;
จบ;
ผลลัพธ์:=pMem;
จบ;
---- 1. คลิกเหตุการณ์ btnSave ที่นี่สาธิตการใช้งาน TMemoryStream อีกครั้ง โดยเขียนข้อมูลใน Stream ไปยังฐานข้อมูล
var
MS: TMemoryStream;
เริ่ม
MS:=TMemoryStream.create;
Image1.Picture.Bitmap.SaveToStream (MS);
MS.ตำแหน่ง:=0;
Table1.ผนวก;
file://เพิ่มบันทึกลงในฐานข้อมูล
TBlobField(Table1.FieldbyName
('รูปภาพ')).LoadFromStream(MS);
Table1.โพสต์;
file://เขียนการอัพเดตไปยังฐานข้อมูล
จบ;
---- 4. คลิกเหตุการณ์ของ DBNavigator1 ที่นี่สาธิตการใช้งาน TBlobStream โดยใช้วิธีอื่นจากการเขียนเพื่ออ่านข้อมูลรูปภาพของฐานข้อมูล
var
MS: ทีสตรีม;
เริ่ม
ด้วย Table1 ทำ
MS:=CreateBlobStream
(FieldbyName('รูปภาพ'),bmRead);
รูปภาพ1.รูปภาพบิตแมป
LoadFromStream(MS);
MS.ฟรี;
จบ;
ขอบคุณที่อ่านบทความนี้ ฉันมีคะแนนไม่เพียงพอที่จะใช้ ดังนั้นฉันจึงต้องสะสมคะแนนเพื่อแลก หากคุณรู้สึกว่าบทความนี้มีประโยชน์สำหรับคุณ โปรดลงคะแนนให้ฉัน ขอบคุณ