[add]
Zitat:
Warum streamst Du diese nicht direkt an den Client?
Wir hatten das Anfangs auch parallel zum DataSnap via
Indy (
TCP) übertragen und über DataSnap nur die Übertragung gesteuert. (Teilweise über DataSnap-Callbacks)
Aber als wir dann rausfanden, warum größere Dateien "nicht" übertragen wurden (falsche Auswertung des Streams), baute ich das dann wieder so um, daß es jetzt nur noch via DataSnap läuft.
[/add]
PS: (Ob das wirklich bei REST geht, weiß ich nicht ... ich glaub wir verwenden JSON oder so ... hab's jetzt nicht mehr im Kopf)
Delphi-Quellcode:
function TServerMethods1.GetFile(Filename, Version:
string): TStream;
begin
Result := GetFile(Filename, Version);
if Result.Size <= 0
then begin
Result.Free;
StringToLogfile(logFileError, '
GetFile: Datei ' + Filename + '
nicht gefunden');
raise Exception.Create('
GetFile: Datei ' + Filename + '
nicht gefunden');
end;
StringToLogfile(logFileInfo, '
GetFile: Datei ' + Filename + '
wurde gefunden');
end;
Auf Clientseite bekommt man da eine Art TMemoryStream an ('ne eigene Klasse des DataSnap), welchen man automatisch vom DataSnap freigeben lassen kann (dem automatisch generierten Client-Modul) oder man gibt es dann selber frei, wenn man es ausgelesen hat.
Delphi-Quellcode:
// Auf Serverseite, wenn man da einen Stream hin überträgt (automatische Freigabe):
procedure TDSFileMethods.Xyz(Stream: TStream);
begin
...
MachWas(Stream);
...
end;
// Auf Clientseite, wenn ein Stream abgerufen wurde (manuelle Freigabe):
var
Stream: TStream;
begin
Stream := DataSnapClientModul.GetStream(...);
try
...
MachWas(Stream);
...
finally
Stream.Free;
end;
end;
// Auf Clientseite, wenn ein Stream abgerufen wurde (automatische Freigabe):
var
Stream: TStream;
begin
Stream := DataSnapClientModul.GetStream(...);
...
MachWas(Stream);
...
end;
Aber wenn du den Stream an eine Komponente weitergeben willst, dann empfehle ich dir den im Clienten umzukopieren, bevor er benutzt wird, denn .Size funktioniert nicht.
Delphi-Quellcode:
procedure FileMethods_CopyStream(Source, Dest: TStream);
var
B: array[1..64*1024] of Byte;
i: Integer;
begin
Source.Position := 0;
repeat
i := Source.Read(B, SizeOf(B));
Dest.WriteBuffer(B, i);
until i < SizeOf(B);
end;
// Auf Serverseite, wenn man da einen Stream hin überträgt (automatische Freigabe):
procedure TDSFileMethods.Xyz(Stream: TStream);
var
Temp: TStream;
begin
Temp := TMemoryStream.Create;
try
FileMethods_CopyStream(Stream, Temp);
...
MachWas(Temp);
...
finally
Temp.Free;
end;
end;
// Auf Clientseite, wenn ein Stream abgerufen wurde (manuelle Freigabe):
var
Temp, Stream: TStream;
begin
Temp := TMemoryStream.Create;
try
Stream := DataSnapClientModul.GetStream(...);
try
FileMethods_CopyStream(Stream, Temp);
finally
Stream.Free;
end;
...
MachWas(Temp);
...
finally
Temp.Free;
end;
end;
// Auf Clientseite, wenn ein Stream abgerufen wurde (automatische Freigabe):
var
Temp: TStream;
begin
Temp := TMemoryStream.Create;
try
FileMethods_CopyStream(DataSnapClientModul.GetStream(...), Temp);
...
MachWas(Temp);
...
finally
Temp.Free;
end;
end;