Hallo Zusammen,
das Problem vorab: Wenn ein Dataset vom DataSnapServer zum einem DataSnapClient transportiert wird welches mehrere
Records beinhaltet die auch ein binary Blob beinhalten, können die Blobinhalte verloren gehen!
Der Blob Inhalt wird massiv vergrössert.
Um das zu demonstrieren habe ich auch eine Testanwendung erzeugt mit einem DataSnapServer und ein DataSnapClient.
Die Datenbank ist eine Firebird
DB mit einer Tabelle. Die Tabelle beinhaltet 15 Records.
Die ersten fünf Bilder sind gleich mit einer Größe von 2kb(2338). Die nächsten fünf Bilder ebenfalls gleich mit 22kb(21959)
und die nächsten fünf Bilder ebenfalls gleich mit einer Größe von 263kb(263368)
(Screen shot "AllImages")
Rufe ich das komplette DataSet mit alle 15 Bilder ab und speichere sie auf der Platte, ist zu sehen:
-die ersten fünf 2kb Bilder sind gleich.
-die nächsten fünf Bilder mit je 22kb wird jedes zweite und den Faktor 100 vergrößert
-die letzten fünf Bilder mit je 263kb sind wieder gleich.
(Screen shot "ImagesOneIaATime")
Rufe ich die Bilder so ab dass das DataSet immer nur ein Record liefert, werden alle 15 Bilder mit der richtigen Größe
abgerufen.
Hat jemand eine Idee warum das so ist?
Dürfen in DataSets die mehr wie ein Record haben keine Blob Felder enthalten, ist da was bekannt?
Kann das auch bei String Blobs passieren?
//Server Methoden um das DataSet zu liefern
Delphi-Quellcode:
function TdmDAL.GetIMAGES: TDataSet;
var
oQuery: TFDQuery;
begin
result := nil;
oQuery := nil;
oQuery := TFDQuery.Create(nil);
try
TThread.Synchronize(nil, procedure
begin
oQuery.Connection := FDConnection1;
oQuery.FetchOptions.AutoFetchAll := afAll;
oQuery.FetchOptions.RecordCountMode := cmTotal;
oQuery.SQL.add('/*Get all images*/');
oQuery.SQL.add('SELECT *');
oQuery.SQL.add('FROM IMAGES');
oQuery.Open;
end);
result := oQuery;
finally
// oQuery.Free;
end;
end;
function TdmDAL.GetIMAGE(ImageID:integer): TDataSet;
var
oQuery: TFDQuery;
begin
result := nil;
oQuery := nil;
oQuery := TFDQuery.Create(nil);
try
TThread.Synchronize(nil, procedure
begin
oQuery.Connection := FDConnection1;
oQuery.FetchOptions.AutoFetchAll := afAll;
oQuery.FetchOptions.RecordCountMode := cmTotal;
oQuery.SQL.add('/*Get all images*/');
oQuery.SQL.add('SELECT *');
oQuery.SQL.add('FROM IMAGES');
oQuery.SQL.add('WHERE IMAGEID = :IMAGEID');
oQuery.Params[0].Value := ImageID;
oQuery.Open;
end);
result := oQuery;
finally
// oQuery.Free;
end;
end;
//Client Methoden um die Images vom Server abzurufen.
Delphi-Quellcode:
Function SaveBlobIntoFile(aField: TField; aFile:
String): Boolean;
Var
S : TStream;
FileS : TFileStream;
begin
Result := False;
If Not aField.IsBlob
Then Exit;
// If aField.IsNull Then EXIT;
S := aField.DataSet.CreateBlobStream(aField, bmRead);
FileS := TFileStream.Create(aFile, fmCreate);
Try
Try
FileS.CopyFrom(S, S.Size);
Result := FileExists(aFile);
Except
on e:
exception Do
Begin
Result := False;
End;
End;
Finally
S.Free;
FileS.Free;
End;
end;
procedure TfrClientMain.Button1Click(Sender: TObject);
var LDataSet: TDataSet;
ImagaPath:
String;
begin
if not dmComm.InitConnection
then exit;
try
LDataSet := dmComm.ClientContainer.FProxyInst.GetIMAGES;
LDataSet.Open;
LDataSet.first;
ImagaPath := ExtractFilePath(Application.ExeName) + '
Images\';
ForceDirectories(ImagaPath);
while not LDataSet.Eof
do
begin
SaveBlobIntoFile(LDataSet.FieldByName('
IMAGE'), ImagaPath + LDataSet.FieldByName('
IMAGEID').AsString+'
.png');
LDataSet.Next;
end;
ShellExecute(
Handle,
nil, PChar(ImagaPath),
nil,
nil, SW_SHOW);
finally
dmComm.CloseConnection;
end;
end;
procedure TfrClientMain.Button2Click(Sender: TObject);
begin
if not dmComm.InitConnection
then exit;
try
Edit1.text := dmComm.ClientContainer.FProxyInst.ReverseString(Edit1.text);
finally
dmComm.CloseConnection;
end;
end;
procedure TfrClientMain.Button3Click(Sender: TObject);
var LDataSet: TDataSet;
ImagaPath:
String;
i:integer;
begin
if not dmComm.InitConnection
then exit;
try
ImagaPath := ExtractFilePath(Application.ExeName) + '
Images\';
ForceDirectories(ImagaPath);
for i := 1
to 15
do
begin
if Assigned(LDataSet)
and LDataSet.Active
then LDataSet.close;
LDataSet := dmComm.ClientContainer.FProxyInst.GetIMAGE(i);
LDataSet.Open;
LDataSet.first;
SaveBlobIntoFile(LDataSet.FieldByName('
IMAGE'), ImagaPath + LDataSet.FieldByName('
IMAGEID').AsString+'
.png');
end;
ShellExecute(
Handle,
nil, PChar(ImagaPath),
nil,
nil, SW_SHOW);
finally
dmComm.CloseConnection;
end;
end;
Gruß Kostas