我编写了一个DataSnap服务器方法,它返回一个TStream对象来传输文件.客户端应用程序调用该方法并正确读取流.我的问题是在TStream对象可用于读取之前,方法调用需要一段时间才能完成,但在服务器端,我可以看到方法调用只需要一秒钟来创建要返回的对象.我希望立即返回流对象,以便我可以读取流并显示下载进度的进度条.还有其他方法可以做到这一点吗?
服务器方法很简单:
- function TServerMethods.DespatchDocument(sCompanyID,sDocOurRef: string): TStream;
- var
- sSourceFilePath: string;
- strFileStream: TFileStream;
- begin
- sSourceFilePath := GetDocumentPDFFilePath(sCompanyID,sDocOurRef);
- strFileStream := TFileStream.Create(sSourceFilePath,fmOpenRead);
- Result := strFileStream;
- end;
解决方法
这就是我一段时间做的.我用XE并没有机会清理它.
//服务器端:
- function TServerMethods1.DownloadFile(out Size: Int64): TStream;
- begin
- Result := TFileStream.Create('upload.fil',fmOpenRead or fmShareDenyNone);
- Size := Result.Size;
- Result.Position := 0;
- end;
//客户端:
- procedure TfMain.DownloadFile(Sender: TObject);
- var
- RetStream: TStream;
- Buffer: PByte;
- Mem: TMemoryStream;
- BytesRead: Integer;
- DocumentId: Int64;
- Size: Int64;
- filename: WideString;
- BufSize: Integer;
- begin
- BufSize := 1024;
- try
- Mem := TMemoryStream.Create;
- GetMem( Buffer,BufSize );
- try
- RetStream := FDownloadDS.DownloadFile(Size);
- RetStream.Position := 0;
- if ( Size <> 0 ) then
- begin
- filename := 'download.fil';
- repeat
- BytesRead := RetStream.Read( Pointer( Buffer )^,BufSize );
- if ( BytesRead > 0 ) then
- begin
- Mem.WriteBuffer( Pointer( Buffer )^,BytesRead );
- end;
- lStatus.Caption := IntToStr( Mem.Size ) + '/' + IntToStr( Size );
- Application.ProcessMessages;
- until ( BytesRead < BufSize );
- if ( Size <> Mem.Size ) then
- begin
- raise Exception.Create( 'Error downloading file...' );
- end;
- end
- else
- begin
- lStatus.Caption := '';
- end;
- finally
- FreeMem( Buffer,BufSize );
- FreeAndNIl(Mem);
- end;
- except
- on E: Exception do
- begin
- lErrorMessage.Caption := PChar( E.ClassName + ': ' + E.Message );
- end;
- end;
- end;
您可以根据需要调整BufSize.我无法获得流的大小,直到我这样做.我尝试使用XE2并没有出现同样的问题,但我上传了.可能有更好的方法来检索流的大小.如果我很快得到答案,我会告诉你……
另一方面 – 我还没想出如何在服务器端显示进度条.我还在努力解决这个问题.
我希望这有帮助!如果您有任何疑问,请告诉我!