Why does this code not work?
I am writing an application that has ability to save and load its own files and need to know how to stream objects to a file using FileStream.
procedure TForm1.btnSaveClick(Sender: TObject);
var
fs: 开发者_JAVA技巧TFileStream;
begin
fs := TFileStream.Create('c:\temp\a.my', fmCreate);
try
fs.WriteBuffer(Image1.Picture.Graphic, SizeOf(TGraphic));
finally
fs.Free;
end;
ShowMessage('ok');
Image1.Picture.Graphic := nil;
end;
procedure TForm1.btnLoadClick(Sender: TObject);
var
fs: TFileStream;
g: TGraphic;
begin
fs := TFileStream.Create('c:\temp\a.my', fmOpenRead);
try
fs.ReadBuffer(g, SizeOf(TGraphic));
Image1.Picture.Graphic := g;
finally
fs.Free;
end;
ShowMessage('ok');
end;
EDIT 1: Found the way to do it, but need some more help:
procedure TForm1.btnSaveClick(Sender: TObject);
var
fs: TFileStream;
s: TMemoryStream;
buf: TBytes;
begin
fs := TFileStream.Create('c:\temp\a.my', fmCreate);
s := TMemoryStream.Create;
try
Image1.Picture.Graphic.SaveToStream(s);
SetLength(buf, s.Size);
s.Position := 0;
s.ReadBuffer(buf[0], s.Size);
//fs.WriteBuffer(, SizeOf(Integer)); <-here how do I save an integer which represents the size of the buffer? (so that when reading back i read this first.)
fs.WriteBuffer(buf[0], s.Size);
finally
s.Free;
fs.Free;
end;
ShowMessage('ok');
Image1.Picture.Graphic := nil;
end;
What you have done there is stream the reference, i.e. a pointer. What you need to stream is the contents. You can that with SaveToFile and LoadFromFile.
Regarding your update, assign s.Size to a local variable of type Integer and then use WriteBuffer to save it. In reverse, use ReadBuffer to read into a local variable.
If I were you I would write direct to the file and avoid the memory streak. Use the Position property of TStream to seek around the file. So write 0 for then length, write the graphic, seek back to the beginning and write the true length accounting for the 4 bytes of the length.
精彩评论