怎么把组件里的内容转成流,需要时再将流转成原来的内容。(50分)

  • 主题发起人 主题发起人 易名烦
  • 开始时间 开始时间

易名烦

Unregistered / Unconfirmed
GUEST, unregistred user!
我是想这样,我把控件中的内容转成流后保存到本地文件。需要时将文件转成流再转成控件
中的内容。
 
procedure TForm1.Button4Click(Sender: TObject);
var
messagepart:tstream;
begin
if not ad1.Active then
ad1.Open;
msg.Clear;
idpop31.Retrieve(strtoint(edit1.Text),msg);
ad1.Append;
ad1.FieldByName('FromName').AsString:=msg.From.Text;
ad1.FieldByName('FromAddress').AsString:=msg.From.Address;
ad1.FieldByName('ToAddress').AsString:=msg.Recipients.EMailAddresses;
ad1.FieldByName('subject').AsString:=msg.Subject;
ad1.FieldByName('date').AsDateTime:=msg.Date;
messagepart:=tstream.Create;
messagepart.ReadComponent(tcomponent(msg.MessageParts));
messagepart.Position:=0;
Tblobfield(ad1.FieldByName('MessageParts')).LoadFromStream(messagepart);
ad1.Post;
end;
运行出错:TStream.Seek not implemented.
 
将 TStream 替换成 TMemoryStream 试一试?
 
没做过,也不会做,不有什么意义。
 
to beta:
现在又提示:Stream read error.
 
TStream是抽象»ùÀ࣬²»¿ÉÒÔÖ±½ÓÓá£ÔÚÄãµÄÓ¦ÓÃÖУ¬Ó¦¸ÃʹÓÃTMemoryStreamÀ´´úÌæTStream
 
TStream是抽象基类,不可以直接用。在你的应用中,应该使用TMemoryStream来代替TStream
 
改成TMemoryStream后提示:Stream read error!
 
看Delphi帮助就行了,有现成的代码:
function ComponentToString(Component: TComponent): string;
var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(Component);
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStream, StrStream);
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free;

end;
finally
BinStream.Free
end;
end;

function StringToComponent(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value);
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStream, BinStream);
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(nil);

finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;
 
ReadComponent 和 WriteComponent
 
写入数据库:
procedure TForm1.Button4Click(Sender: TObject);
var
messagepart:tmemorystream;
begin
if not ad1.Active then
ad1.Open;
msg.Clear;
idpop31.Retrieve(strtoint(edit1.Text),msg);
ad1.Append;
ad1.FieldByName('FromName').AsString:=msg.From.Text;
ad1.FieldByName('FromAddress').AsString:=msg.From.Address;
ad1.FieldByName('ToAddress').AsString:=msg.Recipients.EMailAddresses;
ad1.FieldByName('subject').AsString:=msg.Subject;
ad1.FieldByName('date').AsDateTime:=msg.Date;
messagepart:=tmemorystream.Create;
messagepart.WriteComponent(tcomponent(msg.MessageParts));
messagepart.Seek(0,sofrombeginning);
Tblobfield(ad1.FieldByName('MessageParts')).LoadFromStream(messagepart);
ad1.Post;
end;
从数据库读出:
procedure TForm1.Button5Click(Sender: TObject);
VAR
STRSTREAM:TSTRINGSTREAM;
BINSTREAM:TMEMORYSTREAM;
MESSAGEPART:TIDMESSAGEPARTS;
IT:TLISTITEM;
I:INTEGER;
S:TCOMPONENT;
begin
S:=TCOMPONENT.Create(APPLICATION);
IF NOT AD1.Active THEN
AD1.Open;
STRSTREAM:=TSTRINGSTREAM.Create(AD1.Fields.FieldBYNAME('MESSAGEPARTS').AsString);
BINSTREAM:=TMEMORYSTREAM.Create;
OBJECTTEXTTOBINARY(STRSTREAM,BINSTREAM);
BINSTREAM.Seek(0,SOFROMBEGINNING);
MESSAGEPART:=TIDMESSAGEPARTS.Create(APPLICATION);
BINSTREAM.ReadComponent(S);
MESSAGEPART:=TIDMESSAGEPARTS(S);
end;
写入数据库没问题,读出时出错,提示:OBJECT excepted on line 1.
 
//on line 1
此时光标停留在哪一行?你双击该错误提示可以跳到出错行。

还有,你的 MESSAGEPART 是一个指向与 S 同一个地址,而
S 是局部变量,函数退出的时候空间就被释放了,所以函数
退出过后,你在引用 MESSAGEPART 也会出错。

 

"OBJECT excepted on line 1"不是显示在代码窗口下面的,是直接跳出来的对话框。
另外我变量S并没有用在过程外,处理都是在这个过程内部完成的,只是下面代码有点长
而乱,没好意思贴出来。
 
是想保存什么?是控件的一些属性还是整个控件。
 
是属性,具体一点就是TIDMESSAGE的MESSAGEPARTS(TIDMESSAGEPARTS)。
 
line 1 是哪一行?
 
倒,现在才发现,你写进去的时候是二进制数据,读出来却是用的字符串型:(!!!

那个直接跳出来的对话框你点了确定过后,光标在哪一行?
 
读写的方式不一样!!
STRSTREAM:=TSTRINGSTREAM.Create(AD1.Fields.FieldBYNAME('MESSAGEPARTS').AsString);
如果 MESSAGEPARTS 是TBlobField 用 asstring 合适吗?

读的时候为什么用 TStringStream,也用 TMemorySteam
 
BINSTREAM.Seek(0,SOFROMBEGINNING);
 
可能是因为你读写的方式不一致:
This example shows how to use the built-in VCL component streaming support to convert any component into a string and convert that string back into a component.

function ComponentToString(Component: TComponent): string;

var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(Component);
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStream, StrStream);
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free;

end;
finally
BinStream.Free
end;
end;

function StringToComponent(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value);
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStream, BinStream);
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(nil);

finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;
 
后退
顶部