Jonathan Wareham
Jonathan Wareham

Reputation: 3397

Delphi XE2 DataSnap - Streaming JPEG Files via TStream From Server To Client

I've written a DataSnap server method that returns a TStream object to transfer a file. The client application calls the method and reads the stream to download the file. The server method is very simple :

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

It works fine downloading many file types (PDF, GIF, BMP, ZIP, EXE) but it doesn't work when downloading JPG files. On the client side the stream object returned from the method call is always 0 in size with JPGs. I can successfully stream JPG files locally on my PC, so it must be something to do with DataSnap. I've done some research which suggests DataSnap converts the stream to JSON behind the scenes and there could be a problem with this when it comes to JPG files - can anybody confirm this? On the client side I'm using the TDSRESTConnection to call the server method. I realise I could ZIP the JPG files before streaming, but would rather not have to do this.

Upvotes: 2

Views: 7533

Answers (4)

Rok
Rok

Reputation: 11

Add this line to your DownloadFile method:

GetInvocationMetadata.ResponseContentType := 'image/jpeg';

Upvotes: 1

Jonathan Wareham
Jonathan Wareham

Reputation: 3397

Embarcadero have now come back with a fix to this problem (which also affects .DOC files) :

1.Copy '...\RAD Studio\9.0\source\data\datasnap\Datasnap.DSClientRest.pas' to your DataSnap Client project folder

2.Add the .pas file to the project

3.Modify Line#1288 as below

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

4.Rebuild DataSnap REST Client project

5.Run it with REST Server

This fixes the problem.

Upvotes: 1

Jonathan Wareham
Jonathan Wareham

Reputation: 3397

Just as an update - after further research I've found this is related to the system locale in use on the PC. I'm using 'English (United Kingdom)' but if I change this to for example 'Japan (Japanese)' then the errors disappear and the file transfer works fine. I've logged this as a QC report with Embarcadero.

Upvotes: 1

Jonathan Wareham
Jonathan Wareham

Reputation: 3397

Thought I'd update the thread on my attempts to resolve this. I never found a way to transfer a JPEG file over DataSnap using TStream, but have done it by converting the stream to a TJSONArray and passing this back instead. So my server method now looks as follows:

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

then at the client end I convert back to a TStream with:

strFileStream := TDBXJSONTools.JSONToStream(JSONArray);

I have created this as a new server method call purely for downloading JPEGs, as I've found transferring the files using TJSONArray instead of TStream is as much as 4 times slower, so I use my original method for all other file types.

Upvotes: 3

Related Questions