![]() |
AW: Datasnap File Upload
Sorry, hat mehrfach gepostet.
|
AW: Datasnap File Upload
Zitat:
|
AW: Datasnap File Upload
Um das mal etwas näher zu erläutern: Beim Create eines Proxy kann man als zweiten Parameter angeben, ob der Proxy der InstanceOwner ist. Lässt man diesen Parameter weg, wird true angenommen. Als InstanceOwner kümmert sich der Proxy selbst um die übergebenen und erhaltenen Instanzen. Ich vermute, das ist in diesem Fall auch so. Daher meine Frage nach der Implementation von UploadFile.
|
AW: Datasnap File Upload
Hier ist mein Proxy:
Delphi-Quellcode:
und hier mein Server:
//
// Erzeugt vom DataSnap-Proxy-Generator. // 11.09.2012 15:05:33 // unit proxy; interface uses Data.DBXCommon, Data.DBXClient, Data.DBXDataSnap, Data.DBXJSON, Datasnap.DSProxy, System.Classes, System.SysUtils, Data.DB, Data.SqlExpr, Data.DBXDBReaders, Data.DBXJSONReflect; type TServerMethods1Client = class(TDSAdminClient) private FEchoStringCommand: TDBXCommand; FReverseStringCommand: TDBXCommand; FUploadFileCommand: TDBXCommand; public constructor Create(ADBXConnection: TDBXConnection); overload; constructor Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean); overload; destructor Destroy; override; function EchoString(Value: string): string; function ReverseString(Value: string): string; procedure UploadFile(str: TStream; Store: string; FileName: string); end; implementation function TServerMethods1Client.EchoString(Value: string): string; begin if FEchoStringCommand = nil then begin FEchoStringCommand := FDBXConnection.CreateCommand; FEchoStringCommand.CommandType := TDBXCommandTypes.DSServerMethod; FEchoStringCommand.Text := 'TServerMethods1.EchoString'; FEchoStringCommand.Prepare; end; FEchoStringCommand.Parameters[0].Value.SetWideString(Value); FEchoStringCommand.ExecuteUpdate; Result := FEchoStringCommand.Parameters[1].Value.GetWideString; end; function TServerMethods1Client.ReverseString(Value: string): string; begin if FReverseStringCommand = nil then begin FReverseStringCommand := FDBXConnection.CreateCommand; FReverseStringCommand.CommandType := TDBXCommandTypes.DSServerMethod; FReverseStringCommand.Text := 'TServerMethods1.ReverseString'; FReverseStringCommand.Prepare; end; FReverseStringCommand.Parameters[0].Value.SetWideString(Value); FReverseStringCommand.ExecuteUpdate; Result := FReverseStringCommand.Parameters[1].Value.GetWideString; end; procedure TServerMethods1Client.UploadFile(str: TStream; Store: string; FileName: string); begin if FUploadFileCommand = nil then begin FUploadFileCommand := FDBXConnection.CreateCommand; FUploadFileCommand.CommandType := TDBXCommandTypes.DSServerMethod; FUploadFileCommand.Text := 'TServerMethods1.UploadFile'; FUploadFileCommand.Prepare; end; FUploadFileCommand.Parameters[0].Value.SetStream(str, FInstanceOwner); FUploadFileCommand.Parameters[1].Value.SetWideString(Store); FUploadFileCommand.Parameters[2].Value.SetWideString(FileName); FUploadFileCommand.ExecuteUpdate; end; constructor TServerMethods1Client.Create(ADBXConnection: TDBXConnection); begin inherited Create(ADBXConnection); end; constructor TServerMethods1Client.Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean); begin inherited Create(ADBXConnection, AInstanceOwner); end; destructor TServerMethods1Client.Destroy; begin FreeAndNil(FEchoStringCommand); FreeAndNil(FReverseStringCommand); FreeAndNil(FUploadFileCommand); inherited; end; end.
Delphi-Quellcode:
Was du sagst, mit dem InstanceOwner, verstehe ich. Aber was ist dann der Unterschied zwischen den beiden Funktionen?
unit ServerMethodsUnit1;
interface uses System.SysUtils, System.Classes, Datasnap.DSServer, Datasnap.DSAuth; type {$METHODINFO ON} TServerMethods1 = class(TComponent) private { Private declarations } public { Public declarations } function EchoString(Value: string): string; function ReverseString(Value: string): string; procedure UploadFile(str: TStream; Store, FileName: String); end; {$METHODINFO OFF} implementation uses System.StrUtils; procedure TServerMethods1.UploadFile(str: TStream; Store, FileName: String); var aFileStream: TFileStream; BytesReadCount: Integer; Buffer: array [1 .. 16 * 1024] of Byte; strPfad: String; begin strPfad := 'C:\' + Store; if not DirectoryExists(strPfad) then begin MkDir(strPfad); end; aFileStream := TFileStream.Create(strPfad + '\' + FileName, fmCreate); try repeat BytesReadCount := str.Read(Buffer, SizeOf(Buffer)); aFileStream.Write(Buffer, BytesReadCount); until (BytesReadCount < SizeOf(Buffer)); str.Position := 0; finally aFileStream.Free; end; end; function TServerMethods1.EchoString(Value: string): string; begin Result := Value; end; function TServerMethods1.ReverseString(Value: string): string; begin Result := System.StrUtils.ReverseString(Value); end; end.
Delphi-Quellcode:
in beiden erzeuge ich das Objekt aClient auf die gleiche Weise. Demnach müßte ja in beiden Funktion der gleiche Fehler auftreten. Tut er aber nicht.
procedure TForm2.Button1Click(Sender: TObject);
var aClient: TServerMethods1Client; begin aClient := TServerMethods1Client.Create(SQLCOnnection1.DBXConnection); Try Edit1.Text := aClient.ReverseString(Edit1.Text); Finally aClient.Free; End; end; procedure TForm2.Button2Click(Sender: TObject); var aClient: TServerMethods1Client; aFileStream: TFileStream; begin aClient := TServerMethods1Client.Create(SQLCOnnection1.DBXConnection); Try aFileStream := TFileStream.Create(JvFilenameEdit1.Text, fmOpenRead); try aClient.UploadFile(aFileStream, 'Upload', ExtractFileName(JvFilenameEdit1.Text)); except ShowMessage('Übertragung fehlerhaft!'); end; Finally aFileStream.Free; aClient.Free; End; end; |
AW: Datasnap File Upload
Zitat:
Aus diesem Grund hast du auch bei ReverseString keine Probleme, da dort keine Instanzen freigegeben werden müssen. |
AW: Datasnap File Upload
Das habe ich verstanden. Vielen Dank. Mal sehen, wie weit ich jetzt komme :-D
|
AW: Datasnap File Upload
Datasnap gibt (standardmäßig) Streams frei, welche übertragen wurden, also wenn man die automatisch generierten Clientklassen verwendet.
Wenn du es selbst nochmal freigibst, dann knallt es natürlich. Vertausche mal
Delphi-Quellcode:
und
aFileStream.Free;
Delphi-Quellcode:
, oder kommentiere
aClient.Free;
Delphi-Quellcode:
aus.
aFileStream.Free;
[edit] Komisch, alles ab 13:30 war eben noch nicht sichtbar. :shock: In einer der automatisch generierten Clientklassen baut Delphi ein Property ein, wo du dieses Freigeben deaktivieren kannst. |
AW: Datasnap File Upload
Zitat:
|
AW: Datasnap File Upload
Neee nee, das war nicht zur Fehlerbehandlung ... Ich war nur mal neugierig, wie/ob sich dann die Fehlerposition verschiebt.
Ich bin eher der Meinung, daß der Stream schon direkt nach dem Übertragen freigegeben wird, womit ich schon beim
Delphi-Quellcode:
eine Exception erwartet hätte.
aFileStream.Free;
Hmmmm, aber vielleicht hatte es ja dort geknallt und der Debugger zeigte nur die falsche Codezeile an. (macht er gerne mal, da der Stacktrace die Rücksprungadressen behinhaltet, also den nächsten Befehl) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz