Delphi XE2 DataSnap - 通过TStream从服务器到客户端流式传输JPEG文件

时间:2012-02-03 11:25:37

标签: delphi rest stream jpeg datasnap

我编写了一个DataSnap服务器方法,该方法返回一个TStream对象来传输文件。客户端应用程序调用该方法并读取流以下载该文件。服务器方法非常简单:

function TServerMethods.DownloadFile(sFilePath: string): TStream;
var
  strFileStream: TFileStream;
begin
  strFileStream := TFileStream.Create(sFilePath, fmOpenRead);
  Result := strFileStream;
end;

下载多种文件类型(PDF,GIF,BMP,ZIP,EXE)可以正常工作,但下载JPG文件时不起作用。在客户端,从方法调用返回的流对象的大小始终为0,带有JPG。我可以在PC上本地成功传输JPG文件,因此它必须与DataSnap有关。我做过一些研究,建议DataSnap在幕后将流转换为JSON,当涉及到JPG文件时可能会出现问题 - 任何人都可以证实这一点吗?在客户端,我使用TDSRESTConnection来调用服务器方法。我意识到我可以在流式传输之前压缩JPG文件,但不想这样做。

4 个答案:

答案 0 :(得分:3)

以为我会尝试解决此问题时更新线程。我从来没有找到过使用TStream通过DataSnap传输JPEG文件的方法,但是通过将流转换为TJSONArray并将其传回来完成。所以我的服务器方法现在看起来如下:

function TServerMethods.DownloadJPEGFile(sFilePath: string): TJSONArray;
var
  strFileStream: TFileStream;
begin
  strFileStream := TFileStream.Create(sFilePath, fmOpenRead);
  Result := TDBXJSONTools.StreamToJSON(strFileStream, 0, strFileStream.Size);
end;

然后在客户端我转换回TStream:

strFileStream := TDBXJSONTools.JSONToStream(JSONArray);

我已经创建了这个纯粹用于下载JPEG的新服务器方法调用,因为我发现使用TJSONArray而不是TStream传输文件的速度要慢4倍,所以我将原始方法用于所有其他文件类型

答案 1 :(得分:1)

就像更新一样 - 经过进一步研究后,我发现这与PC上使用的系统区域设置有关。我正在使用'英语(英国)',但如果我将其更改为例如'Japan(Japanese)',则错误消失,文件传输正常。我已将此记录为Embarcadero的QC报告。

答案 2 :(得分:1)

Embarcadero现在已经回来修复了这个问题(也会影响.DOC文件):

1.Copy'... \ RAD Studio \ 9.0 \ source \ data \ datasnap \ Datasnap.DSClientRest.pas'到您的DataSnap客户端项目文件夹

2.将.pas文件添加到项目

3.修改第1288行,如下所示

//  LResponseJSON := TJSONObject.ParseJSONValue(BytesOf(LResponseText.StringValue), 0);
LResponseJSON := TJSONObject.ParseJSONValue(BytesOf(UTF8String(LResponseText.StringValue)), 0);

4.Rebuild DataSnap REST客户端项目

5.使用REST服务器运行

这解决了这个问题。

答案 3 :(得分:0)

将此行添加到您的DownloadFile方法:

GetInvocationMetadata.ResponseContentType := 'image/jpeg';