Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Upload großer Dateien (https://www.delphipraxis.net/205442-upload-grosser-dateien.html)

OlliWW 10. Sep 2020 09:00

Upload großer Dateien
 
Hallo,

Ich möchte aus meiner Anwendung per HTTP(s) Dateien auf meinen Webserver übertragen. Diese Dateien sind sehr groß (immer < 1 GB, bis zu 20 GB).

Nun könnte ich mit den Indy HTTP Komponenten einfach einen Stream "Posten" und so die Daten an meinen Webserver übergeben. Ich habe nun allerdings schon vielfach gelesen, dass es bei großen Dateien zu Problemen mit der Dateigröße kommt, da diese dann zunächst in den Arbeitsspeicher geladen wird und dann in einem Stück gepostet wird.

Kennt jemand einen guten Weg, große Dateien per HTTPS zu übertragen? Vielleicht eine Komponenten die die File in Chunks aufteilt oder ähnliches?

Andere Protokolle (FTP, SFTP,...) kommen leider nicht in Frage.

Der schöne Günther 10. Sep 2020 09:13

AW: Upload großer Dateien
 
Ohne wirklich etwas in der Richtung gemacht zu haben würde ich behaupten dass die angesprochenen Probleme daher kommen, wenn man die Dateien (die ja schon irgendwo auf der Platte liegen) wirklich mit Methoden wie LoadFromFile(..) oder ähnliches reinlädt oder an Indy übergibt.

Ich habe mit Indy nie viel gemacht, aber neben Dateien hat das Ding garantiert Unterstützung für Streams. Dann nimmst du einen TFileStream (oder TBufferedFileStream) und gibst das weiter.

himitsu 10. Sep 2020 10:25

AW: Upload großer Dateien
 
Unabhängig davon, ob die Übertragung über den RAM, eine FileCahe oder direkt abläuft, hat z.B. PHP (was ist dein WebServer?) einige LIMITs bei der Größe der POST-Daten und dem RAM.
https://stackoverflow.com/questions/...a-post-request

Auch deswegen übertragen viele Webseiten Uploads via JavaScript (AJAX und Co.) ... teilen es da auf und führen intern z.B. mehrere HTTP-Requests durch.



Es gibt auch WebDAV-Implementationen die mit PHP/JavaScript laufen und in "normale" Webseiten integriert werden könnten.
Als Beispiel ist z.B. im Bei Google suchenownCloud sowas drin

OlliWW 10. Sep 2020 10:27

AW: Upload großer Dateien
 
Über die Serverseite hatte ich mir auch schon Gedanken gemacht.

Wenn man den Upload aufteilen will, dann müsste man auf der Programm-Seite den Stream auch in "Chunks" aufteilen und irgendwie ein intelligentes Script auf der Serverseite schreiben, dass die Chunks wieder zusammenbaut.

Ich denke ich könnte das alles implementieren, ich hatte aber gehofft, dass es dafür schon ein Framwork gibt.

Aufteilen hätte auch den Vorteil, dass man das sogar multithreaded laufen lassen könnte, um mehr Bandbreite zu nutzen.

KodeZwerg 10. Sep 2020 10:39

AW: Upload großer Dateien
 
Zitat:

Zitat von OlliWW (Beitrag 1473365)
Aufteilen hätte auch den Vorteil, dass man das sogar multithreaded laufen lassen könnte, um mehr Bandbreite zu nutzen.

Vorweg, ich bin kein Internet/Delphi experte.

Das verstehe ich nicht, sind deine einzelnen Verbindungen von der Gesamtbandbreite beschränkt so das ein multi-connect tatsächlich mehr speed bringt?

Ansonsten würde ich meinen das so ein vorhaben eher kontra-produktiv ist da immer ein Paket auf ein anderes warten muss um wieder ein ganzes zu werden.

himitsu 10. Sep 2020 10:52

AW: Upload großer Dateien
 
Eventuell/Vermutlich kannst bei deinem Webserver auch etwas über CGI oder ASP nachrüsten
und z.B. am PHP vorbei mit Perl oder Python und in Windows-Servern sogar als EXE/DLL.
http://www.virtualuniversity.ch/soft...mierung/1.html

Mit einem Rootserver (auch bei virtual und dedicated) wäre aber etwas Eigenes via TCP/IP bestimmt einfacher
und kann man auch über JavaScript clientseitig von der Webseite ansprechen.
Bei uns redet z.B. demnächst ein WebClient mit dem in Delphi geschriebenem DataSnap-Server (REST).

Für andere Platformen, wie z.B. Adroid auf einem Tablet mit Laser-Barcodescanner, nutzen wir kein Delphi. (Embarcadero war da einfach zu langsam und hat es verkackt)

P_G 10. Sep 2020 12:12

AW: Upload großer Dateien
 
Kommt sowas in Frage?

https://www.dropzonejs.com/

Das arbeitet bei großen Dateien automatisch mit Chunks und hat noch ein paar andere nützliche Features an Bord (Progressbar, Preview-Images, etc.). Außerdem ist es gratis.

OlliWW 10. Sep 2020 12:22

AW: Upload großer Dateien
 
Vielen Dank für die vielen hilfreichen Hinweise.

Ich implementiere es gerade so:
- Intelligentes PHP Script dass immer Teile einer Datei annimmt sowas wie: upload.php?file=test.bin&chunk=4711 (auf dem Server werden die Chunks abgelegt: test.bin_4711
- Delphi teilt den Stream in 10 MB Teile und läd die an das o.g. PHP Script (idHTTP Post)
- Am Ende poste ich ein "finish" an das Script und das Script setzt (wenn die Chunks durchgehend sind) die File dann wieder zusammen

Damit muss ich das ganze nicht sequentiell abarbeiten und kann theoretisch paralell mehrere Teile übertragen (muss aber nicht)

Was ich durch das Teilen leider verliere ist die Möglichkeit einen Upload weiter durchzuführen, falls er abbricht. Normal könnte ich mit "Head" prüfen, wie groß die File auf dem Server ist und an dieser Stelle weiter machen, aber in meinem Szenario kann ich das denke ich vernachlässigen.

sakura 10. Sep 2020 12:27

AW: Upload großer Dateien
 
Vorschlag, so kenne ich es von anderen Systemen.

Im ersten Schritt den Upload registrieren mit Gesamtgröße in Bytes und einer Chunkgröße, dann kannst Du diese auch ggf. anpassen, wenn mal eine schlechte Verbindung besteht. Der Server antwortet mit einer Upload-ID. Du kannst übrigens auf modernen Windows-Rechnern direkt eine Datei mit der gewünschten Größe anlegen (dauert nur ein paar Millisekunden, FileStream.Size := AnzahlderBytes)

Dann im Upload nur die Chunk# und Upload-ID übergeben und diese dann direkt in die Zieldatei schreiben. Des Weiteren hast Du eine Bitmap für alle Chunks, und setzt das entsprechende Bit, wenn ein Chunk oben ist. Dann musst Du abschließend nicht ein "Fertig" senden. Außerdem kannst Du somit auch einen Upload fortsetzen, da der Server dem Client auch antworten kann, ob ein Chunk bereits existiert ;-)

...:cat:...

OlliWW 10. Sep 2020 12:29

AW: Upload großer Dateien
 
Cool Danke! :thumb:

Beach 10. Sep 2020 12:32

AW: Upload großer Dateien
 
Denkst du nicht, das du beim zusammensetzen mittels PHP wieder an die Grenzen stößt?
Wird außerdem sehr inperformant sein.

Vielleicht solltest du mal eher in Richtung sFTP bzw FTPS schauen?
Je nachdem was dein Server für Möglichkeiten bietet?

OlliWW 10. Sep 2020 12:34

AW: Upload großer Dateien
 
Zitat:

Zitat von Beach (Beitrag 1473378)
Vielleicht solltest du mal eher in Richtung sFTP bzw FTPS schauen?
Je nachdem was dein Server für Möglichkeiten bietet?

Die derzeitige Lösung ist: SFTP
Das Problem ist nicht der Server, das Problem ist der Client, in manchen Fällen macht mir die Client Firewall einen Strich durch die Rechnung und darauf habe ich nicht immer Zugriff. Auch SSHd auf Port 443 laufen zu lassen löst das Problem nicht immer, da manche Firewalls mit DPI erkennen, dass dies keine richtige HTTPS Connection ist.

Blup 11. Sep 2020 11:14

AW: Upload großer Dateien
 
Zitat:

Zitat von OlliWW (Beitrag 1473375)
- Am Ende poste ich ein "finish" an das Script und das Script setzt (wenn die Chunks durchgehend sind) die File dann wieder zusammen

Vorschlag:
Am Anfang Dateiname, Länge, Chunk-Länge und Prüfsumme der Datei übertragen.
Der Server kann aufgrund dieser Informationen prüfen, ob für diese Datei schon eine Teilübertragung stattgefunden hat.
Sollte sich die gemerkte Prüfsumme der Datei unterscheiden, wurde die Datei auf dem Client inzwischen verändert und muss komplett neu übertragen werden.
Server legt die Datei sofort in der Gesamtlänge mit temporären Namen an (Speicher ist reserviert, vermindert Fragmentierung).
Server teilt mit welche Chunks noch benötigt werden.

Client überträgt Chunks, vieleicht sogar mehrere parallel (spart die Latenzzeit).
Server schreibt jeden Chunk direkt in die Datei ab der Position, an die der Chunk gehört.
Streicht die übertragenen Chunk aus seiner Liste.

Client meldet Abschluss.
Server prüft ob noch Chunk fehlen > Fehler Rückmeldung > fehlende Chunk übertragen
Server prüft CRC > Fehler Rückmeldung > Abbruch
Server benennt die temporäre Datei um und gibt die nur für die Übertragung erforderlichen Daten frei.

Es sollte auch ein Mechanismus existieren, die Übertragungen vom Client aus endgültig abzubrechen.

MyRealName 11. Sep 2020 11:17

AW: Upload großer Dateien
 
Man könnte auch einfach das Torrent-Prokoll abwandeln oder gleich torrent nutzen :) Ist ja nicht illegal für eigene Dateien :p

himitsu 11. Sep 2020 12:09

AW: Upload großer Dateien
 
Zitat:

Zitat von MyRealName (Beitrag 1473424)
oder gleich torrent nutzen

Ja, das Protokoll an sich ist nicht illegal,
aber wenn mehrere Programme auf den Handies mehrerer User sich gegenseitig die Dateien austauschen,
dann hätte da vielleicht der Datenschutz ä bissl was dagegen. :zwinker:

Zum Runterladen von Dateien isses OK, aber beim Hochladen "privater" Dateien sollte man aufpassen.
Zumindestens wenn es unverschlüsselt passiert und jeder es runterladen könnte (nicht nur dein "Server"), sonst könnte man es wenigstens noch als Backup deklarieren.


PS: Er will ja grade hin zu HTTP(s)-Basierendem und weg von was Anderem, weil es Probleme mit Firewalls und Dergleichen gibt,
was ein "böses" FileSharing-Protokoll nicht grade verbessern würde. :angle2:
Zitat:

Zitat von OlliWW (Beitrag 1473379)
Das Problem ist nicht der Server, das Problem ist der Client, in manchen Fällen macht mir die Client Firewall einen Strich durch die Rechnung und darauf habe ich nicht immer Zugriff.


Michael II 14. Sep 2020 11:00

AW: Upload großer Dateien
 
Ich kenne Indy zu wenig, aber mit ICSOverbyte (via GetIt erhältlich) ist das Übertragen von grossen Files problemlos machbar.

Mit ICS werden viele Beispielprogramme installiert. Ein ftp Beispiel findest du unter
C:\Users\...\Dokumente\Embarcadero\Studio\21.0\Cat alogRepository\ICS_FMX-8.64-Sydney\Samples\Delphi\FtpDemos ( Du schreibst, dass ftp auf einigen Systemen blockiert wird. Dann würde man wohl am besten diese Hindernisse aus dem Weg räumen.)

Auch ohne ftp, zum Beispiel via ICSOverbytes TWSocket funktioniert der Upload von sehr grossen Files problemlos. Wie weiter oben erwähnt wird, sollte deine Programm nach einem Verbindungsunterbruch nicht wieder bei 0 beginnen müssen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:21 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