Kolben make_response mit großen Dateien
So, ich bin echt grün mit Datei-I/O-und memory-limits und solche, und ich habe eine harte Zeit immer meine web-Anwendung erfolgreich bedienen zu große Datei-downloads, um einen web-browser, der Kolben ist make_response
. Der folgende code funktioniert bei kleineren Dateien (<~1 GB), aber gibt mir ein MemoryError
Ausnahme, wenn ich in größeren Dateien:
raw_bytes = ""
with open(file_path, 'rb') as r:
for line in r:
raw_bytes = raw_bytes + line
response = make_response(raw_bytes)
response.headers['Content-Type'] = "application/octet-stream"
response.headers['Content-Disposition'] = "inline; filename=" + file_name
return response
Ich gehe davon aus, dass kleben über 2 GB im Wert von Binärdaten in eine Zeichenfolge ist wahrscheinlich eine große no-no, aber ich weiß nicht, eine alternative zur Bewältigung dieser Datei-download schwarze Magie. Wenn jemand könnte mich auf die richtige Spur mit einem klobigen[?] oder gepufferten Ansatz für die Datei-downloads, oder einfach nur zeigen Sie mir die Richtung intermediate-level-Ressourcen zur Verfügung, die ein tieferes Verständnis von diesem Zeug, ich würde es sehr zu schätzen. Danke!
- Warum Lesen die Datei überhaupt? Sie können benutzen Sie einfach die
send_file()
- Funktion zu haben Kolben die Datei für Sie. - Weil ich nichts von der Existenz einer solchen Funktion 😀 nur ich überarbeitet der Umsetzung, es zu benutzen und jetzt habe ich ein anderes Problem; es scheint die Erinnerung an die erste Datei eines bestimmten Typs, die geöffnet wird, und die Verwendung dieser für alle nachfolgenden Dateien dieses Typs. dh, wenn ich ein paar png-Dateien, eine pdf-Datei und eine txt-Datei, wird die Anwendung erfolgreich heruntergeladen die erste richtige png, und dann servieren Sie das gleiche Bild für alle anderen, verschiedene png-Datei. Auf der server-Seite, ich habe festgestellt, dass die send_file-Funktion wird der richtige Pfad zu den pngs, aber es immer noch falsch verhält.
- Dann etwas anderes ist immer noch falsch; das ist nicht das Verhalten, dass
send_file()
auf seine eigene produzieren kann.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Siehe die Dokumentation auf Streaming-Inhalte. Im Grunde, Sie schreiben eine Funktion, die Erträge Stücke von Daten, und pass generator, um die Antwort, anstatt die ganze Sache auf einmal. Kolben und Ihr web-server erledigen den rest.
Wenn die Datei statisch ist, können Sie stattdessen nutzen
send_from_directory()
. Die docs empfehlen Ihnen die Nutzung von nginx oder ein anderer server, unterstützt X-SendFile, so dass das Lesen und senden der Daten ist effizient.Das problem in Ihrem Versuch ist,, dass Sie in Erster Lesung kompletten Inhalt in "raw_bytes", also mit großen Dateien, die Sie sind einfach zu erschöpft alle Speicher, den Sie haben.
Gibt es mehrere Möglichkeiten, die:
Streaming der Inhalte
Wie erläutert durch davidism beantworten, können Sie einen generator weitergegeben int Antwort. Dies dient der großen Datei Stück für Stück und braucht nicht so viel Speicher.
Dem streaming kann nicht nur von einem generator, sondern auch aus einer Datei, wie in dieser Antwort
Statischen Dateien über Kolben
Falls Ihre Datei ist statisch, Suche nach, wie man konfigurieren Kolben zu dienen, die statische Dateien. Diese werden automatisch serviert streaming-Weise.
Statischen Dateien über
apache
odernginx
(oder anderen web-server)Vorausgesetzt, die Datei ist statisch, Sie sind in der Produktion dienen Sie durch reverse-proxy vor deiner Flasche-app. Dadurch wird nicht nur entlastet Ihre app, sondern funktioniert auch viel schneller.