2

我编写了一个 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

4 回答 4

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 倍,因此我将原始方法用于所有其他文件类型。

于 2012-02-09T16:58:12.767 回答
1

就像更新一样 - 经过进一步研究,我发现这与 PC 上使用的系统区域设置有关。我正在使用“英语(英国)”,但如果我将其更改为“日本(日语)”,那么错误就会消失并且文件传输工作正常。我已将此记录为 Embarcadero 的 QC 报告。

于 2012-03-26T09:06:28.627 回答
1

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

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

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

3.修改Line#1288如下

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

4.重建DataSnap REST Client项目

5.使用REST服务器运行它

这解决了问题。

于 2012-04-03T09:36:06.363 回答
1

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

GetInvocationMetadata.ResponseContentType := 'image/jpeg';
于 2015-05-04T07:14:31.533 回答