AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Datasnap File Upload
Thema durchsuchen
Ansicht
Themen-Optionen

Datasnap File Upload

Ein Thema von BeBored · begonnen am 3. Dez 2011 · letzter Beitrag vom 12. Sep 2012
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von BeBored
BeBored

Registriert seit: 2. Jun 2004
Ort: Cremlingen
90 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Datasnap File Upload

  Alt 3. Dez 2011, 18:24
Hallo,
ich sitze in der Arbeit an einer Client/Server Anwendung die wir mit Datasnap realisieren.
Sonst lief auch alles, nur seit heute bekomme ich beim Upload einer Datei eine Exception.
Über einen TOpenDialog wählt man eine Datei. Die wird mit Pfad in eine Listbox eingetragen (lbFiles).
Hier der Client:
aFileStream: TFileStream;
Delphi-Quellcode:
for i := 0 to lbFiles.Items.Count - 1 do
  begin
    aFileStream := TFileStream.Create(lbFiles.Items[i], fmOpenRead);
    if aClient.UploadFile(aFileStream, Store, ExtractFileName(lbFiles.Items[i])) then // Hier exception!
      begin
        Konsole.TextHinweis(ExtractFileName(lbFiles.Items[i]) + ' gesendet!');
      end;
  end;
Die Exception:
Exception-Klasse TDBXError mit Meldung 'Remote-Fehler: Ungültiger Dateiname - %s'.

Der Server:
Delphi-Quellcode:
const
  BufferSize = 1024;
var
  aFileStream: TFileStream;
  Buffer: TBytes;
  BytesReadCount: Integer;
  Success: boolean;
begin
  Success := false;
  if not DirectoryExists(ExtractFilePath(ParamStr(0)) + 'Files\') then
  begin
    MkDir(ExtractFilePath(ParamStr(0)) + 'Files\' + Store);
  end;
  try
    if FileExists(Name) then
    begin
      DeleteFile(Name);
    end;
    aFileStream := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'Files\' + Name, fmCreate);
    SetLength(Buffer, BufferSize);
    repeat
      BytesReadCount := str.Read(Buffer[0], BufferSize);
      if (BytesReadCount > 0) then
        aFileStream.Write(Buffer[0], BytesReadCount);
    until (BytesReadCount < BufferSize);
    str.Position := 0;
    Success := True;
  finally
    aFileStream.Free;
    SetLength(Buffer, 0);
  end;
  Result := Success;
end;
Ich verstehe nicht wo der Fehler liegt, weil gestern noch alles lief...
Hat wer eine Idee?
Matthias
Wer nichts wagt der nichts verliert.
  Mit Zitat antworten Zitat
Benutzerbild von BeBored
BeBored

Registriert seit: 2. Jun 2004
Ort: Cremlingen
90 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Datasnap File Upload

  Alt 3. Dez 2011, 22:52
In der Listbox steht übrigens der richtige Pfad mit der richtigen Datei. Store und Name sind nur für den Server und soweit ich das sehe auch nicht das Problem.
Matthias
Wer nichts wagt der nichts verliert.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#3

AW: Datasnap File Upload

  Alt 3. Dez 2011, 23:01
Einzig ungewöhlich finde ich den Parameter "Name"
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#4

AW: Datasnap File Upload

  Alt 3. Dez 2011, 23:05
Jupp, wo "Name" doch ein beliebtes property in allen VCL-Komponenten ist.

Zitat:
Delphi-Quellcode:
MkDir(ExtractFilePath(ParamStr(0)) + 'Files\' + Store)
FileExists(Name)
DeleteFile(Name)
TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'Files\' + Name)

Mit Pfad, ohne Pfad, Pfad mit Store oder Pfad ohne Store?
Delphi-Quellcode:
ExtractFilePath(ParamStr(0)) + 'Files\' + Store
Name
ExtractFilePath(ParamStr(0)) + 'Files\' + Name
PS: Daß die DP Name fett darstellt, sollte dir schon zu Denken geben.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von BeBored
BeBored

Registriert seit: 2. Jun 2004
Ort: Cremlingen
90 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Datasnap File Upload

  Alt 3. Dez 2011, 23:16
Ja stimmt mit Name und habe ich (VNC sei dank) auch gleich geändert aber der Fehler kommt nach wie vor am Client.
Ist Store '00000' dann wird die Datei im Ordner Files gespeichert, ist sie anders (z.B. 52125) dann wird der Ordner 52125 in Files angelegt und die Datei dort gespeichert. Der Server liefert auch kein False zurück, bis dahin kommt er garnicht.

...hab es jetzt gefunden... der Fehler war das ich auf Files geprüft habe aber dann immer Files\00000 anlegen wollte. nenene

Ne das war es doch nicht...
Matthias
Wer nichts wagt der nichts verliert.

Geändert von BeBored ( 3. Dez 2011 um 23:27 Uhr) Grund: Fehler gefunden - doch nicht
  Mit Zitat antworten Zitat
Benutzerbild von BeBored
BeBored

Registriert seit: 2. Jun 2004
Ort: Cremlingen
90 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

AW: Datasnap File Upload

  Alt 3. Dez 2011, 23:40
Hier mal die Upload Methode
Delphi-Quellcode:
function TServerMethodsClient.UploadFile(str: TStream; Store: string; fName: string): Boolean;
begin
  if FUploadFileCommand = nil then
  begin
    FUploadFileCommand := FDBXConnection.CreateCommand;
    FUploadFileCommand.CommandType := TDBXCommandTypes.DSServerMethod;
    FUploadFileCommand.Text := 'TServerMethods.UploadFile';
    FUploadFileCommand.Prepare;
  end;
  FUploadFileCommand.Parameters[0].Value.SetStream(str, FInstanceOwner);
  FUploadFileCommand.Parameters[1].Value.SetWideString(Store);
  FUploadFileCommand.Parameters[2].Value.SetWideString(fName);
  FUploadFileCommand.ExecuteUpdate; // Genau hier gibt es dann die Exception
  Result := FUploadFileCommand.Parameters[3].Value.GetBoolean;
end;
Vielleicht hilft es ja
Matthias
Wer nichts wagt der nichts verliert.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.541 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Datasnap File Upload

  Alt 3. Dez 2011, 23:45
FUploadFileCommand.Text := 'TServerMethods.UploadFile';
Sollte es nicht besser LoadFromFile heißen statt der direkten Zuweisung? Ich kann aber auch mal wieder alles falsch verstehen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von BeBored
BeBored

Registriert seit: 2. Jun 2004
Ort: Cremlingen
90 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: Datasnap File Upload

  Alt 3. Dez 2011, 23:49
FUploadFileCommand.Text := 'TServerMethods.UploadFile';
Sollte es nicht besser LoadFromFile heißen statt der direkten Zuweisung? Ich kann aber auch mal wieder alles falsch verstehen.
Das wurde von Delphi oder besser von der TSQLConnection erstellt. Das wird auch jedesmal wenn ich eine neue Methode implementiere überschrieben.
Matthias
Wer nichts wagt der nichts verliert.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.541 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Datasnap File Upload

  Alt 3. Dez 2011, 23:51
Jo, dann hab ich das wohl falsch interpretiert, ich hab auch ehrlich gesagt keinen Plan von DataSnap.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#10

AW: Datasnap File Upload

  Alt 3. Dez 2011, 23:53
Delphi-Quellcode:
var
  aFileStream: TFileStream;
  Buffer: array[1..16*1024] of Byte; // 16 KB
  BytesReadCount: Integer;
begin
  if not DirectoryExists(ExtractFilePath(ParamStr(0)) + 'Files') then
    MkDir(ExtractFilePath(ParamStr(0)) + 'Files\' + Store);
  aFileStream := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'Files\' + FileName, fmCreate);
  try
    repeat
      BytesReadCount := str.Read(Buffer, SizeOf(Buffer));
      aFileStream.Write(Buffer, BytesReadCount);
    until BytesReadCount < SizeOf(Buffer);
  finally
    aFileStream.Free;
  end;
end;
Beschreibung:
  • fmCreate überschreibt bestehende Dateien ... es ist also nicht nötig diese vorher zu löschen
  • Das .Create gehört vor den Try-Finally-Block, denn wenn es vor dem .Create schon knallt, dann knallt es im Finally nochmals beim .Free, da die Variable nicht initialisiert hattest.
    > Tipp: Hör auf das, was dir der Compiler sagt, denn der hat dich ganz bestimmt gewarnt.
    Ausnahme: Man initialisiert die Variable vorher entsprechend mit NIL.
  • Dynamische Arrays (z.B. TBytes) und Strings muß man nicht unbedingt manuell freigeben.
    Vorallem wenn Delphi das eine Millisekune später auch nochmal macht ... Im geheimen/unsichtbaren END-Code deiner Methode.
  • Da du eh mit einer Konstanten Puffergröe arbeitest, kannst du den Puffer auch gleich konstannt erstellen.
    > 16 KB sollten locker nich mit noch auf deinen Stack drauf passen ... wenn nicht, dann stimmt eh irgendwo etwas nicht.
  • 1 KB ist eh etwas "suboptimal"
    DataSnap hat standardmäßig einen Übertragungspuffer von 32 KB und auch die Clustergröße deiner Festplatte (die Größe der Verwaltungseinheiten) wird bei dir bestimmt mehr als ein 1 KB sein.
  • Name > FileName
  • das Success ist vollkommen "sinnlos"
    • Erstemal kannst du deine werte direkt an result übergeben und brauchst keine susätzliche Variable.
      (ist nicht wie beim Return in C, PHP, JS und Co., wo bei dessen Zuweisung die Prozedur beendet wird)
    • außerdem gibt dein Resul keinen "sinnvolen" Wert zurück.
      • es gibt True zurück, wenn alles (vermutlich) erfolgreich war
        (ist nicht wie beim Return in C, PHP, JS und Co., wo bei dessen Zuweisung die Prozedur beendet wird)
      • bei einem Fehler gibt es eine Exception und das Result wird nicht verwendet
      Also reicht eine Proedure ... Fehler werden ja eh als Exception zurückgegeben.

      Die Exceptions jetzt abzufangen (try-except) wäre ganz schlimm, denn ein Boolean sagt nur daß etwas falsch lief,
      aber die Exception, welche gesagt hätte was genau nichtr ging, hätte man dann geschrottet.

      Im Server also einfach procedure UploadFile(Stream: TStream; StorePath, FileName: string); verwenden.

PS: Sollte die Datei im Store-Pfad liegen, oder hab ich das falsch verstanden?
Wenn ja, dann muß "Store" natürlich noch mit in den Pfad des TFileStream.Create aufgenommen werden.


Zitat:
Das wird auch jedesmal wenn ich eine neue Methode implementiere überschrieben.
Du mußt das ja auch im Server ändern ... dann wird es im Clienten richtig importiert.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 4. Dez 2011 um 00:04 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz