莫名其妙的问题

ninestar 2000-07-31 09:09:00
本人问题如下:
由一个Table控件(tab_tmp),其中有一个字段 'TEXT' 为ftBlob类型
保存数据的代码如下:
procedure Tmain.bt_saveClick(Sender);//保存按扭(bt_save)的OnClick事件
var
l_Stream:TBlobStream;
MemSize: Integer;
Buffer: PChar;
MyFile: TFileStream;
Stream: TBlobStream;
begin

if FileExists('tmp.doc') then DeleteFile('tmp.doc');
l_Ole.SaveToFile('tmp.doc');
MyFile:=TFileStream.Create('tmp.doc',fmOpenRead);
Stream := TBlobStream.Create(tab_ht_mb.fieldbyname('TEXT') as TBlobField, bmWrite);
//tab_ht_mb.fieldbyname('TEXT') 类型为fbBlob(DB2数据库)
MemSize := MyFile.Size;
Inc(MemSize);
Buffer := AllocMem(MemSize);
try
tab_ht_mb.Edit; //tab_ht_mb为TTable控件
Stream.Seek(0, soFromBeginning);
MyFile.Read(Buffer^,MemSize);
Stream.Write(Buffer^,MemSize);
finally
MyFile.Free;
Stream.Free;
end;
with tab_ht_mb do
begin
ApplyUpdates;
CommitUpdates;
end;
end;

以上代码都能正常保存数据,但是在新增(或删除)一条记录保存后,再通过
TTable.Prior的方法后不能刷新ToleContailer中的内容(发生'Stream read error' 错误,
后跟踪l_Stream的长度发现为4,非正常长度),(而TTable.Next,TTable.Last,TTable.First)
方法可以刷新ToleContainer中的内容我是在TTable的AfterScroll的事件中刷新ToleContainer的内容,
代码如下:
procedure TForm_ht_sz02.tab_ht_mbAfterScroll(DataSet: TDataSet);
var
l_Stream:TStream;
begin
try
l_Stream:=tab_ht_mb.CreateBlobStream(tab_ht_mb.fieldbyname('TEXT') asTBlobField,bmRead);
//tab_ht_mb为TTable控件
l_ole.LoadFromStream(l_Stream) (此句产生'Stream read error'错误)
//l_ole为ToleContainer控件
except
end;
l_Stream.Free;
end;
以上'Stream read error'的错误只要是通过保存(删除)记录后,再通过TTable.Prior方法,移到当前保存(或删除)的记录的
前面任意一条记录都会出现,本人反复调试都由该错误发生,忘各位大虾不吝指教!!!!!!!!
...全文
174 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
lotto 2000-08-07
  • 打赏
  • 举报
回复
在DB2中将TAble设置Cacheupdate设置为True,无论是否使用事务,都容易产生这个错误,因为你的ole只能读些Word8.0文档的内容,且blob字段在applyupdates后,产生了不可预知的错误,建议你重新连接表,再通过标签定位到原来的记录。
ninestar 2000-08-07
  • 打赏
  • 举报
回复
这是应用程序读Blob字段时发生了错误,需要正确设置blob size和Blob cache。
ninestar 2000-08-07
  • 打赏
  • 举报
回复
这好象是一个Bug,你可以将Table断开,再连接应该可以解决
Wingsun 2000-08-02
  • 打赏
  • 举报
回复
我想可能的问题处在Stream的读写上。改成如下代码试一试:
try
tab_ht_mb.Edit; //tab_ht_mb为TTable控件
Stream.Seek(0, soFromBeginning);
MyFile.Seek(0,soFromBeginning);//新增的
MyFile.Read(Buffer^,MemSize);
Stream.Write(Buffer^,MemSize);
finally
try
l_Stream:=tab_ht_mb.CreateBlobStream(tab_ht_mb.fieldbyname('TEXT') asTBlobField,bmRead);
//tab_ht_mb为TTable控件
l_Stream.Seek(0,soFromBeginning);//new line
l_ole.LoadFromStream(l_Stream) (此句产生'Stream read error'错误)
//l_ole为ToleContainer控件
except
end;
l_Stream.Free;
其实你上面的语句可以改成不使用中间临时文件的方法。TOleContainer有一个方法SaveToStream和LoadFromStream.
我用BCB实现的代码如下:
TBlobStream * pData=(TBlobStream *)pQuery->CreateBlobStream(pQuery->FieldByName("Text"),bmWrite);
pData->Seek(0,soFromBeginning);
ocDocument->SaveToStream(pData);
pQuery->Post();
然后装载时:
TBlobStream * pData;
TBlobField * pField=(TBlobField *)pQuery->FieldByName("Text");
pData=new TBlobStream(pField,bmRead);
pData->Seek(0,soFromBeginning);
ocDocument->LoadFromStream(pData);
delete pData;
JGTM2000 2000-07-31
  • 打赏
  • 举报
回复
我大概看了一下,TOleContainer的LoadFromStream是让其中包含的OLE对象去从流中加载数据,而你的OLE对象是否可以读取Delphi TDataset的CreateBlobStream生成的流呢?应该不行吧,因为她能读的流是要符合一种规范的,至少要有12字节的头,这显然和TBlobStream生成的流是不同的(除非你数据库里面存的BLOB就是OLE对象SaveToStream生成的流)。因此马上就会产生stream read error的异常。

你能说说你的目的吗?

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧