如何在 Delphi XE6 中使用 DataSnap 传递和 return 流?
How to pass and return a Stream using DataSnap in Delphi XE6?
如何在 Delphi XE6 中使用 DataSnap 传递和 return 流?
当我调用我的服务器端方法时,我的流是正确的 class,具有大小和位置。然而,当它到达我的客户时, class 不是我所期望的,它没有大小或位置
//客户端代码
procedure TForm1.brnGetReportClick(Sender: TObject);
var
RunReportObj: TRunReportObject;
S: TStream;
FS: TFileStream;
begin
....
try
S:= (ClientModule1.ServerMethods1Client.getReport(RunReportObj));
//ShowMessage('Class = ' + S.ClassName + #10#13 +
// 'Size = ' + intToStr(S.Size) + #10#13 +
// 'Position = ' + intToStr(S.Position));
S.Position:= 0;
FS:= TFileStream.Create('test.rpt', fmCreate or fmOpenWrite);
FS.Position:= 0;
try
FS.CopyFrom(S, S.Size);
finally
FS.Free;
end;
finally
S.Free
end;
end;
我上面代码中的调试showmessage,显示如下
Class = TDBXStreamReaderStream
Size = -1
Position = 0
//服务器端方法
function getReport(const ARunReportObj: TRunReportObject): TStream;
var
r: String;
SS: TStringStream;
begin
result:= TMemoryStream.Create;
r := getRunReportJSON(ARunReportObj);
SS := TStringStream.Create(r, TEncoding.ASCII);
try
try
ServerContainer1.idHttp1.Post
('https://imserver1.runit.com/isapi/isellitreporttest.dll/isellit', SS, result);
ShowMessage('Class = ' + Result.ClassName + #10#13 +
'Size = ' + intToStr(result.Size) + #10#13 +
'Position = ' + intToStr(result.Position));
Result.Position:= 0;
except
end;
finally
SS.Free;
end;
end;
我上面代码中的调试showmessage,显示如下
Class = TMemoryStream
Size = 373760
Position = 373760
这是设计好的。 DataSnap 仅保证您从服务器获得 TStream
,而不保证它实际上是 class。您可以阅读它,仅此而已。
Position = 0
也是预期的,因为这是您在服务器中设置的。另一方面,我不确定其他 Position = 0
是否有用,所以如果您在客户端获得 Position = 0
我也不会感到惊讶。虽然,当服务器之前未将其设置为 0 时,流可能不会从预期位置开始。
关于 Size
属性 我参考了 TStream
文档:
The Size property typically indicates the size of the stream in bytes. But a descendent of TStream can use -1 to indicate an unknown size. When the size is unknown, use the return value from TStream.Read to determine end of the stream.
您应该知道 DataSnap 不一定会通过调用 getReport
来传输流内容,但当您从客户端调用 Read
时可能会这样做。这允许像电影或广播播客这样的无限流。
服务器:
客户端到服务器
function Tform_methodos.SendStream(st:TStream): string;
var sm : TMemoryStream;
begin
...
sm:=TMemoryStream.create;
sm.LoadFromStream(st);
sm.SaveToFile(pasta+'\test.bin');
sm.free;
end;
服务器到客户端:
function Tform_methodos.GetStream(var size : integer):Tstream;
begin
...
result:=TmemoryStream.create;
TmemoryStream(result).LoadFromFile('test.bin');
size:=TmemoryStream(result).Size;
end;
客户:
客户端到服务器
var sm : TMemoryStream
error : string;
begin
...
sm:=TMemoryStream.create;
sm.LoadFromFile('test.bin');
error:=server.SendStream(sm);
sm.Free;
end;
服务器到客户端
var sm : TmemoryStream;
st : TStream;
size : integer;
begin
...
sm:=TMemorystream.create;
st:=server.GetStream(size);
sm.CopyFrom(st,size);
sm.SaveToFile('test.bin');
sm.free;
end;
如何在 Delphi XE6 中使用 DataSnap 传递和 return 流?
当我调用我的服务器端方法时,我的流是正确的 class,具有大小和位置。然而,当它到达我的客户时, class 不是我所期望的,它没有大小或位置
//客户端代码
procedure TForm1.brnGetReportClick(Sender: TObject);
var
RunReportObj: TRunReportObject;
S: TStream;
FS: TFileStream;
begin
....
try
S:= (ClientModule1.ServerMethods1Client.getReport(RunReportObj));
//ShowMessage('Class = ' + S.ClassName + #10#13 +
// 'Size = ' + intToStr(S.Size) + #10#13 +
// 'Position = ' + intToStr(S.Position));
S.Position:= 0;
FS:= TFileStream.Create('test.rpt', fmCreate or fmOpenWrite);
FS.Position:= 0;
try
FS.CopyFrom(S, S.Size);
finally
FS.Free;
end;
finally
S.Free
end;
end;
我上面代码中的调试showmessage,显示如下
Class = TDBXStreamReaderStream
Size = -1
Position = 0
//服务器端方法
function getReport(const ARunReportObj: TRunReportObject): TStream;
var
r: String;
SS: TStringStream;
begin
result:= TMemoryStream.Create;
r := getRunReportJSON(ARunReportObj);
SS := TStringStream.Create(r, TEncoding.ASCII);
try
try
ServerContainer1.idHttp1.Post
('https://imserver1.runit.com/isapi/isellitreporttest.dll/isellit', SS, result);
ShowMessage('Class = ' + Result.ClassName + #10#13 +
'Size = ' + intToStr(result.Size) + #10#13 +
'Position = ' + intToStr(result.Position));
Result.Position:= 0;
except
end;
finally
SS.Free;
end;
end;
我上面代码中的调试showmessage,显示如下
Class = TMemoryStream
Size = 373760
Position = 373760
这是设计好的。 DataSnap 仅保证您从服务器获得 TStream
,而不保证它实际上是 class。您可以阅读它,仅此而已。
Position = 0
也是预期的,因为这是您在服务器中设置的。另一方面,我不确定其他 Position = 0
是否有用,所以如果您在客户端获得 Position = 0
我也不会感到惊讶。虽然,当服务器之前未将其设置为 0 时,流可能不会从预期位置开始。
关于 Size
属性 我参考了 TStream
文档:
The Size property typically indicates the size of the stream in bytes. But a descendent of TStream can use -1 to indicate an unknown size. When the size is unknown, use the return value from TStream.Read to determine end of the stream.
您应该知道 DataSnap 不一定会通过调用 getReport
来传输流内容,但当您从客户端调用 Read
时可能会这样做。这允许像电影或广播播客这样的无限流。
服务器:
客户端到服务器
function Tform_methodos.SendStream(st:TStream): string;
var sm : TMemoryStream;
begin
...
sm:=TMemoryStream.create;
sm.LoadFromStream(st);
sm.SaveToFile(pasta+'\test.bin');
sm.free;
end;
服务器到客户端:
function Tform_methodos.GetStream(var size : integer):Tstream;
begin
...
result:=TmemoryStream.create;
TmemoryStream(result).LoadFromFile('test.bin');
size:=TmemoryStream(result).Size;
end;
客户: 客户端到服务器
var sm : TMemoryStream
error : string;
begin
...
sm:=TMemoryStream.create;
sm.LoadFromFile('test.bin');
error:=server.SendStream(sm);
sm.Free;
end;
服务器到客户端
var sm : TmemoryStream;
st : TStream;
size : integer;
begin
...
sm:=TMemorystream.create;
st:=server.GetStream(size);
sm.CopyFrom(st,size);
sm.SaveToFile('test.bin');
sm.free;
end;