procedure TForm1.Button6Click(Sender: TObject);
 var
      Buf:  Variant;
      BufLen:   Integer;
      stream1:TMemoryStream;
  begin
   stream1:=TMemoryStream.Create;
   stream1.SetSize(4096);
       while   True   do   begin
          Buf   :=   ADOQuery1.Recordset.Fields['blo'].GetChunk(4096);
         
          buf.savetostream(stream1); //就是这里不行,怎样把buf 的内容传送到stream1?
         end;
           
  end;

解决方案 »

  1.   

    使用 stream1:=buf 也不行
      

  2.   

    如果你是想读取二进制数据的话可以用:
    blobStrm: TStream;
    stream1:TMemoryStream; 
    blobStrm = ADOQuery1.CreateBlobStream(ADOQuery1.FieldByName('blo'), bmRead);stream1.CopyFrom(blobStrm, blobStrm.Size);
    这样就直接到Stream中去了。
      

  3.   

    关键是你这个VARIANT实际是什么类型?
      

  4.   

    就是像你那样做也不能直接显示进度吧,也是需要通过其它方式来实现的。如果非要显示进度也可以呀,在stream1.CopyFrom(blobStrm, blobStrm.Size); 的时候一次只copy十分之一,界面显示进度,然后再继续
      

  5.   

    Stream1.Write(Buf, Length(Buf));
      

  6.   

    问题的原型:我是在blob字段中存了比较大的数据(几到几十M),然后放到公网上,用户把这些资料下载到本地上再打开。但现在的问题是:用select blo from table1 where ... 打开表时,这个blob字段就开始传送了,这时程序就没有反应了,若数据很大时,往往要等十几分钟,但是看不到进度的话,用户以为程序死掉了。以上所有的方法都是在打开表之后操作的,但等打开后数据已经传过来了,用以上什么方法都不重要了。如何能做到打开表时,不要blob字段传送,而根据用户需要再传,同时显示进度。
      

  7.   

    这个我倒感觉是设计上的问题了。为什么要把几天几十M的数据放到数据库中里,你真接将这些BLOB数据存放到服务器上的文件里面,然后在数据库中存放这个文件的路径就好了,用户需要显示那个数据就去取那个数据对应的文件,从服务器取文件的进度也好显示一些。
      

  8.   

    没错,很多的PACS处理影像文件就是如8楼所说,放在数据中的访问速度是慢的,尤其是并发访问比较多的情况下。
      

  9.   

    我记得好像DataSet可以控制打开表时是否连同blob字段的内容一起传送过来。其实,你完全可以在打开表的查询语句中,不包含blob字段,而在实际需要blob字段的时候,通过当前记录的主键去单独查询这个blob字段,如果这个字段很大,可以放在线程中后台下载(后台下载需要控制好线程同步,因为下载和显示进度不在一个线程中),不过,几十M的东西,再怎么控制还是会很久的,除非网络环境非常好,服务器的负载和很低。你可以在前台做个动画,比如弄个label,让这个label的caption显示 ...... 显示到一定成都后,就从头再显示,或者弄三个字符 /-\ 反复显示,呵呵,总之是让前台动起来,下载放在线程中,呵呵
      

  10.   

    procedure VariantToStream(const Data: OleVariant; Stream: TStream);
    var
      p: Pointer;
    begin
      p := VarArrayLock(Data);
      try
        Stream.Write(p^, VarArrayHighBound(Data, 1) + 1);
      finally
        VarArrayUnlock(Data);
      end;
    end;