Mega Code Archive

 
Categories / Delphi / Examples
 

Storing data into a stream and reading it back

Title: Storing data into a stream and reading it back. Question: I've posted this question before with little to no results. However, if you want to be able to add files & record-structures into a single file - here is one of three examples I came up with. Answer: TempRec = record mFullName:String[25]; mSalary:String[10]; mDept:String[25]; end; var Form1: TForm1; MyData:TempRec; jpg:TJpegImage; St:TMemoryStream; S1:TStream; implementation {$R *.dfm} uses Jpeg; ................................ procedure TForm1.SpeedButton1Click(Sender: TObject); var BS,FS:TStream; sl:TStringList;// Create an index-table? Bm:TBookMark; begin FFileName:=ExtractFilePath(Application.ExeName)+'DATA.DBM'; FS:=TFileStream.Create(FFileName,fmCreate or fmOpenRead); // Keep this file open... Bm:=Query3.GetBookmark; Query3.First; Query3.DisableControls; sl:=TStringList.Create; While Not Query3.Eof do // Loop it... begin BS:=Query3.CreateBlobStream(Query3.FieldByName('EmpPict') as TBlobField, bmRead); try sl.Add(IntToStr(FS.Position)); //!! Store the positions to file... MyData.mFullName:=Query3.FieldByName('FullName').AsString; MyData.mSalary:=Query3.FieldByName('Salary').AsString; MyData.mDept:=Query3.FieldByName('Dept').AsString; FS.Write(MyData.mFullName,SizeOf(Mydata.mFullName)); FS.Write(MyData.mSalary,SizeOf(Mydata.mSalary)); FS.Write(MyData.mDept,SizeOf(Mydata.mDept)); FS.CopyFrom(BS,BS.Size); // Copy the Blob data finally BS.Free;// Free blob!!! Query3.Next; end; sl.SaveToFile(ChangeFileExt(FFileName,'.MDX')); // Our indexes... end; sl.Free; FS.Free; Query3.GotoBookmark(Bm); Query3.FreeBookmark(Bm); Query3.EnableControls; end; // The program that reads and displays unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,Jpeg, ComCtrls, Buttons; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Panel1: TPanel; Image1: TImage; ListBox2: TListBox; Label1: TLabel; Label2: TLabel; bFirst: TSpeedButton; bPrev: TSpeedButton; bNext: TSpeedButton; bLast: TSpeedButton; OpenDialog1: TOpenDialog; Label3: TLabel; Label4: TLabel; Label5: TLabel; cmdLoad: TSpeedButton; procedure ListBox2Click(Sender: TObject); procedure bLastClick(Sender: TObject); procedure bFirstClick(Sender: TObject); procedure bNextClick(Sender: TObject); procedure bPrevClick(Sender: TObject); procedure cmdLoadClick(Sender: TObject); private { Private declarations } Procedure UpdateButtons; public { Public declarations } end; TempRec = record mFullName:String[25]; mSalary:String[10]; mDept:String[25]; end; var Form1: TForm1; FS:TStream; Data:TStream; jpg:TJpegImage; NumRecs:Integer; MyData:TempRec; implementation var FileName:string; {$R *.dfm} Procedure TForm1.UpdateButtons; begin if ListBox2.Items.Count = 1 then begin ListBox2.Selected[0]:=True; ListBox2.OnClick(NIL); bNext.Enabled:=False; bFirst.Enabled:=False; bPrev.Enabled:=False; bLast.Enabled:=False; end else begin ListBox2.Selected[0]:=True; ListBox2.OnClick(NIL); bNext.Enabled:=True; bFirst.Enabled:=True; bPrev.Enabled:=True; bLast.Enabled:=True; end; end; procedure TForm1.ListBox2Click(Sender: TObject); begin { Just a little position filtering...} try StrToInt(ListBox2.Items[ListBox2.ItemIndex]); Except Exit; end; Data:=TMemoryStream.Create; jpg:=TJpegImage.Create; FS:=TFileStream.Create(FileName,fmOpenRead); try { Add the Jpeg Image from our free blob into the "Data Stream".} Data.CopyFrom(FS,FS.Size); { Find the position the (Data Stream) and go to it. No need to worrie about reading pass the Stream; We have the exact position!} Data.Seek(StrToInt(listBox2.Items[ListBox2.ItemIndex]),soFromBeginning); { Our TempRec size only consist of 63~ bytes; you should use (SizeOF() instead...} Data.Read(MyData.mFullName,25); Data.Read(MyData.mSalary,10); Data.Read(MyData.mDept,25); Edit1.Text:=MyData.mFullName; Edit2.Text:=MyData.mSalary; Edit3.Text:=MyData.mDept; { Read beyond the 63 or so bytes and locate the Jpeg Image...} Data.Seek( StrToInt(listBox2.Items[ListBox2.ItemIndex]) + 60 ,soFromBeginning); if Data nil then begin try jpg.LoadFromStream(Data); Image1.Picture.Assign(jpg); Except Image1.Picture :=nil; end; end; finally FS.Free; jpg.Free; Data.Free; end; { Update the UI...} Label1.Caption:=Format('Record %d of %d',[ListBox2.ItemIndex + 1,NumRecs]); if ListBox2.Selected[0] =True then begin bNext.Enabled:=True; bLast.Enabled:=True; bFirst.Enabled:=False; bPrev.Enabled:=False; end else begin bFirst.Enabled:=True; bPrev.Enabled:=True; end; if ListBox2.Selected[NumRecs -1]=True then begin bNext.Enabled:=False; bLast.Enabled:=False; bFirst.Enabled:=True; bPrev.Enabled:=True; end else begin bNext.Enabled:=True; bLast.Enabled:=True; end; end; //--------------------------------- Free Navigator ---------------------------- procedure TForm1.bFirstClick(Sender: TObject); begin With ListBox2 do begin Selected[0]:=True; OnClick(NIL); bFirst.Enabled:=False; bPrev.Enabled:=False; bNext.Enabled:=True; bLast.Enabled:=True; end; end; procedure TForm1.bPrevClick(Sender: TObject); begin (Instead of a ListBox, a StringList works much faster...} With ListBox2 do begin if ItemIndex = 0 then begin bFirst.OnClick(Self); Exit; end; Selected[ListBox2.ItemIndex - 1 ]:=True; OnClick(NIL); bFirst.Enabled:=True; bPrev.Enabled:=True; bNext.Enabled:=True; bLast.Enabled:=True; end; end; procedure TForm1.bNextClick(Sender: TObject); begin With ListBox2 do begin if ItemIndex = NumRecs -1 then begin bLast.OnClick(Self); Exit; end; Selected[ListBox2.ItemIndex + 1 ]:=True; OnClick(NIL); bFirst.Enabled:=True; bPrev.Enabled:=True; bNext.Enabled:=True; bLast.Enabled:=True; end; end; procedure TForm1.bLastClick(Sender: TObject); begin With ListBox2 do begin Selected[NumRecs-1]:=True; OnClick(NIL); bFirst.Enabled:=True; bPrev.Enabled:=True; bNext.Enabled:=False; bLast.Enabled:=False; end; end; procedure TForm1.cmdLoadClick(Sender: TObject); begin if not OpenDialog1.Execute then Exit; FileName:=OpenDialog1.FileName; try ListBox2.Items.LoadFromFile(ChangeFileExt(FileName,'.MDX')); Except MessageDlg('Error while loading Index file!',mtError,[mbAbort],0); Exit; end; NumRecs:=ListBox2.Items.Count; ListBox2.Selected[0]:=True; UpdateButtons; ListBox2.OnClick(Self); end; end.