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
Benutzerbild von himitsu
himitsu

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

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.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 4. Dez 2011 um 00:04 Uhr)
  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 4. Dez 2011, 01:13
Danke für deine Hilfe zu so später Stunde.
Ich habe deine Änderungen jetzt umgesetzt und mit Server+Client auf einem Rechner funktioniert es auch, aber sobald ich den Server extern öffne und dann übertragen will, gibt es wieder die gleiche Exception.
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
 
#3

AW: Datasnap File Upload

  Alt 4. Dez 2011, 01:24
Soweit ich bisher feststellen kann, wird der richtige Dateiname übertragen, aber die Dateien sind immer nur 1024 byte groß.
Die Exception kommt natürlich auch
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
 
#4

AW: Datasnap File Upload

  Alt 4. Dez 2011, 01:31
Das ist bisher der Server:
Delphi-Quellcode:
procedure TServerMethods.UploadFile(str: TStream; Store, FileName: string);
var
  aFileStream: TFileStream;
  BytesReadCount: Integer;
  Buffer: array [1 .. 16 * 1024] of Byte;
begin
  if not DirectoryExists(ExtractFilePath(ParamStr(0)) + 'Files\' + Store) then
  begin
    MkDir(ExtractFilePath(ParamStr(0)) + 'Files\' + Store);
  end;
  aFileStream := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'Files\' + Store + '\' + FileName, fmCreate);
  try
    repeat
      BytesReadCount := str.Read(Buffer, BufferSize);
      aFileStream.Write(Buffer, BytesReadCount);
    until (BytesReadCount < SizeOf(Buffer));
    str.Position := 0;
  finally
    aFileStream.Free;
  end;
end;
Und der Client:
Delphi-Quellcode:
procedure TfrmMain.btnSendClick(Sender: TObject);
var
  aFileStream: TFileStream;
  i: Integer;
begin
  if lbFiles.Count > 0 then
  begin
    try
      for i := 0 to lbFiles.Items.Count - 1 do
      begin
        aFileStream := TFileStream.Create(lbFiles.Items[i], fmOpenRead);
        try
          begin
            aClient.UploadFile(aFileStream, Store, ExtractFileName(lbFiles.Items[i]));
            lbFiles.Clear;
          end
        except
          begin
            ShowMessage('Übertragung fehlerhaft!');
          end;
        end;
      end;
    finally
      aFileStream.Free;
      btnSend.Enabled := False;
    end;
  end
  else
  begin
    Konsole.TextHinweis('Keine Dateien zum Senden vorhanden.');
  end;
end;
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
 
#5

AW: Datasnap File Upload

  Alt 4. Dez 2011, 01:40
Grad gesehen das ich ein SizeOf(Buffer) vergessen hatte. Nun wird die komplette Datei übertragen und eine Exception gibt es auch nicht mehr.

Vielen Dank für die späte Hilfe!
Matthias
Wer nichts wagt der nichts verliert.
  Mit Zitat antworten Zitat
Gor1

Registriert seit: 11. Mai 2011
32 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Datasnap File Upload

  Alt 10. Jan 2012, 10:35
Hallo,

ich habe die Upload-Routine aus dem obigen Beispiel auf Delphi 2009 bzw. Delphi XE2 ausprobiert, allerdings bekomme ich beim zweiten Aufruf der UploadFile-Methode im Client eine Exception (bzw. auch bei der Freigabe des DataSnap-Datenmoduls auf dem Client). Ich habe dann mal die Freigabe des aFileStream im Client auskommentiert, damit funktioniert es dann.
Komischerweise scheint es aber auch keine Speicherlecks (auf dem Client) zu geben, jedenfalls liefert FastMM keine. Irgendwo scheint der Stream also dann doch freigegeben zu werden.

Hier meine Upload-Routine, die mehrfach aufgerufen wird:
Delphi-Quellcode:
    
procedure UploadFile(PfadName, FileName: String);
    var lFileStream: TFileStream;
    begin
      if (FileName <> '') and FileExists(PfadName + FileName) then
      begin
        lFileStream := TFileStream.Create(PfadName + FileName, fmOpenRead);
        try
          try
            DataModule.ServerMethods1Client.UploadFile(lFileStream, 'KundeXY', FileName);
          except
            ShowMessage('Übertragung fehlerhaft!');
          end;
        finally
// lFileStream.Free;
        end;
      end;
    end;
Hat einer von euch eine Idee, warum das so ist?
Es funktioniert zwar grundsätzlich so, aber es bleibt ein ungutes Gefühl, wenn ein lokales Objekt erzeugt wird aber dann nicht mehr (explizit) freigegeben wird.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Datasnap File Upload

  Alt 10. Jan 2012, 10:53
allerdings bekomme ich beim zweiten Aufruf der UploadFile-Methode im Client eine Exception
Wie lautet die Exception-Message (daß man auch immer wieder erts nachfragen muß ) und wie ist die Servermethode implementiert?

irgendwo = Wenn man sagt der Owner soll es machen, dann macht Er (DataSnap) das auch.


Tipp:
Delphi-Quellcode:
procedure UploadFile(PfadName, FileName: String);
    var lFileStream: TFileStream;
    begin
      if (FileName <> '') and FileExists(PfadName + FileName) then
      begin
        lFileStream := TFileStream.Create(PfadName + FileName, fmOpenRead);
        try
          try
            DataModule.ServerMethods1Client.UploadFile(lFileStream, 'KundeXY', FileName);
          except
            ShowMessage('Übertragung fehlerhaft!');
          end;
        finally
          if not DataModule.InstanceOwner then // DataSnap ist hier einfach nur blöd implementiert, also besser so
            lFileStream.Free;
        end;
      end;
    end;
PS: Bei Streams mit (standardmäßig) über 29 KB muß man etwas aufpassen.

PPS:

Eine bessere treffendere Namensgebung wäre auch nicht unbedingt zu verachten. (z.B. alternativ zu den Vorgabewerten DataModule und ServerMethods1Client)

ShowMessage('Übertragung fehlerhaft!'); ... Und was lief schief? ... das weiß nun keiner mehr.
stattdessen eventuell sowas:
Delphi-Quellcode:
except
  on E: Exception do
    ShowMessage('Übertragung fehlerhaft!' + sLineBreak + E.Message);
end;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (10. Jan 2012 um 11:02 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


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 15:59 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