我是先在客户端把STREAM进行压缩。压缩方法是这样子的:
ys:=TCompressionStream.Create(clMax,outstream);   
ys.CopyFrom(instream,0);                          //instream是待压缩的流
ys.Free;
jy:=TDeCompressionStream.Create(outstream);
jy.Position:=0;
然后把压缩后的流转换成VARIANT传递到应用服务器端。应用服务器端接收到以后先把VARIANT转换成STREAM,然后把STREAM解压缩。语句如下:
//对压缩流outstream进行解压
  jy:=TDeCompressionStream.Create(ysstream);    //ysstream是解压后的流
  jy.Position:=0;
  //然后读出解压缩后流的内容
  jyRead := jy.Read(buf, ysstream.Size);   //这句就报错了。而且就报“ERROR”,没报别的。
但是我试过,如果其中少了对流压缩和解压的过程,直接把STREAM转换成VARIANT.然后VARIANT转换成STREAM,最后读出STREAM的内容。那么过程就很顺利。

解决方案 »

  1.   

    具体看一下我的代码吧。原因很简单:
    jyRead := jy.Read(buf, ysstream.Size);   //这句就报错了。而且就报“ERROR”,没报别的。
    实际报错的是ysstream.Size,所以我在处理这个问题的时候是先,将这个大小写入压缩流前面,然后在解压缩前,先读取该数值,然后不用yestream.Size,而用那个读取出来的数据。先是压缩流:
    procedure TFilePacket.PackStream(var Stream: OleVariant);
    var
      ZStream: TCompressionStream;
      InStream:TMemoryStream;
      TempStream:TMemoryStream;
      BStream:TMemoryStream;
      Param:OleVariant;
      p:Pointer;
      pi:Pointer;
      pj:Pointer;
      bSize:int64;
    begin
      InStream:=TMemoryStream.Create;
      BStream:=TMemoryStream.Create;
      TempStream:=TMemoryStream.Create;
      pi:=VarArrayLock(Stream);
      try
         TempStream.Write(pi^,VarArrayHighBound(Stream,1)+1);//这里是实际的数据流
         ZStream:=TCompressionStream.Create(cldefault, InStream);
         try
            ZStream.CopyFrom(TempStream,0);//将实际数据流压缩
         finally
            ZStream.Free;
         end;
         Param:=VarArrayCreate([0,InStream.Size-1+sizeof(bSize)],varByte);
         p:=VarArrayLock(Param);
         try
            pj:=Addr(bSize);
            bSize:=TempStream.Size;//获取实际流的长度
            BStream.Write(pj^,sizeof(bSize));//写入实际流的长度
            BStream.Position:=sizeof(bSize);
            InStream.Position:=0;
            BStream.CopyFrom(InStream,InStream.Size);//接着实际流长度数据后面写入压缩流
            bstream.Position:=0;
            BStream.Read(p^,BStream.Size);
         finally
            VarArrayUnlock(Param);
         end;
      finally
         VarArrayUnlock(Stream);
         InStream.Free;
         TempStream.Free;
         BStream.Free;
      end;
      Stream:=Param;
    end;读数据流:
    procedure TFilePacket.UnPackStream(var Stream: OleVariant);
    var
      TempStream:TMemoryStream;
      OutStream:TMemoryStream;
      ZStream: TDecompressionStream;
      BStream:TMemoryStream;
      Param:OleVariant;
      p:Pointer;
      po:Pointer;
      bSize:int64;
      pj:Pointer;
    begin
      TempStream:=TMemoryStream.Create;
      BStream:=TMemoryStream.Create;
      OutStream:=TMemoryStream.Create;
      p:=VarArrayLock(Stream);
      try
         TempStream.Write(p^,VarArrayHighBound(Stream,1)+1);//还原为数据流
         pj:=Addr(bSize);
         TempStream.Position:=0;
         TempStream.Read(pj^,sizeof(bSize));//读出实际流的大小
         TempStream.Position:=sizeof(bSize);//移动指针到压缩流的起始位置
         if TempStream.Size>0 then BStream.CopyFrom(TempStream,TempStream.Size-sizeof(bSize));//读出压缩
         BStream.Position:=0;
         ZStream:=TDecompressionStream.Create(BStream);//解压缩
         zstream.Position:=0;
         try
            OutStream.CopyFrom(ZStream,bSize);//还入实际流的长度,而不是使用BStream或ZStream的Size属性
            Param:=VarArrayCreate([0,OutStream.Size-1],varByte);
            po:=VarArrayLock(Param);
            try
               OutStream.Position:=0;
               OutStream.Read(po^,OutStream.Size);
            finally
               VarArrayUnlock(Param);
            end;
         finally
            ZStream.Free;
         end;
      finally
         VarArrayUnlock(Stream);
         BStream.Free;
         OutStream.Free;
         TempStream.Free;
      end;
      Stream:=Param;
    end;
      

  2.   

    原文:
    OutStream.CopyFrom(ZStream,bSize);//还入实际流的长度,而不是使用BStream或ZStream的Size属性更正为:
    OutStream.CopyFrom(ZStream,bSize);//带入实际流的长度,而不是使用BStream或ZStream的Size属性
      

  3.   

    再说了,如果YSSTREAM.SIZE报错的话。那应该bsize:=ysstream.size也应该报错啊。可是没有报错。
      

  4.   

    把你的VARIANT和STREAM相互转换的代码贴出来看看。多半是转换出来的就不对了
      

  5.   

    我相信VARIANT和STREAM相互转换的代码肯定是正确的。因为流不压缩,直接转换。然后到服务器端再转换成STREAM的话,是正常的。
      

  6.   

    试试这两个函数:
    procedure Compress(InStream,OutStream:TStream); //压缩函数
    var tmp:TCompressionStream;
        Count:integer;
        buffer:pointer;
    begin
      Count:=Instream.Size ;
      OutStream.Writebuffer(Count,sizeof(integer));
      tmp:=TCompressionStream.Create(clmax,OutStream);
      try
        InStream.Position :=0;
        getmem(buffer,Count);
        try
          InStream.Readbuffer(buffer^,Count);
          tmp.Writebuffer(buffer^,Count);
        finally
          freemem(buffer);
        end;
      finally
        tmp.Free ;
      end;
    end;procedure DeCompress(InStream,OutStream:TStream);//解压函数
    var tmp:TDeCompressionStream;
        Count:integer;
        buffer:pointer;
    begin
      InStream.Position :=0;
      InStream.Readbuffer(Count,sizeof(integer));
      tmp:=TDeCompressionStream.Create(InStream);
      try
        getmem(buffer,Count);
        try
          tmp.Readbuffer(buffer^,Count);
          OutStream.Writebuffer(buffer^,Count);
        finally
          freemem(buffer);
        end;
      finally
        tmp.Free ;
      end;
    end;
      

  7.   

    也许是你的压缩函数不支持TCompressionStream类的