Ich verwende derzeit ein node.js-Plugin namens s3-upload-stream, um sehr große Dateien an Amazon S3 zu streamen. Es verwendet die mehrteilige API und funktioniert größtenteils sehr gut.
Dieses Modul zeigt jedoch sein Alter an und ich musste bereits Änderungen daran vornehmen (der Autor hat es ebenfalls abgelehnt). Heute bin ich auf ein anderes Problem mit Amazon gestoßen, und ich würde gerne die Empfehlung des Autors annehmen und anfangen, das offizielle aws-sdk zu verwenden, um meine Uploads durchzuführen.
ABER.
Das offizielle SDK scheint Piping to nicht zu unterstützen s3.upload()
. Die Natur von s3.upload ist, dass Sie den lesbaren Stream als Argument an den S3-Konstruktor übergeben müssen.
Ich habe mehr als 120 Benutzercodemodule, die verschiedene Dateiverarbeitungen durchführen, und sie sind unabhängig vom endgültigen Ziel ihrer Ausgabe. Der Motor gibt ihnen einen ableitbaren, beschreibbaren Ausgabestream und sie leiten ihn weiter. Ich kann ihnen kein AWS.S3
Objekt geben und sie bitten, es aufzurufen upload()
, ohne allen Modulen Code hinzuzufügen. Der Grund, den ich benutzte, s3-upload-stream
war, dass es Rohrleitungen unterstützte.
Gibt es eine Möglichkeit, aws-sdk zu s3.upload()
etwas zu machen , zu dem ich den Stream leiten kann?
s3
param im rohr undstream
kommt von?Eine etwas späte Antwort, es könnte hoffentlich jemand anderem helfen. Sie können sowohl den beschreibbaren Stream als auch das Versprechen zurückgeben, sodass Sie nach Abschluss des Uploads Antwortdaten erhalten.
Und Sie können die Funktion wie folgt verwenden:
Jetzt können Sie entweder das Versprechen überprüfen:
Oder als
stream.pipe()
Rückgabe stream.Writable, das Ziel (writeStream-Variable oben), das eine Kette von Pipes zulässt, können wir auch seine Ereignisse verwenden:quelle
In der akzeptierten Antwort endet die Funktion, bevor der Upload abgeschlossen ist, und ist daher falsch. Der folgende Code leitet einen lesbaren Stream korrekt weiter.
Referenz hochladen
Sie können auch noch einen Schritt weiter gehen und Fortschrittsinformationen wie folgt ausgeben
ManagedUpload
:ManagedUpload-Referenz
Eine Liste der verfügbaren Ereignisse
quelle
TypeError: dest.on is not a function
eine Idee warum?dest.on
? Können Sie ein Beispiel zeigen? @ FireBrandTyp-Skript-Lösung: In
diesem Beispiel wird Folgendes verwendet:
Und asynchrone Funktion:
Nennen Sie diese Methode irgendwo wie:
quelle
Keine der Antworten hat bei mir funktioniert, weil ich wollte:
s3.upload()
s3.upload()
in einen anderen StreamDie akzeptierte Antwort macht das letztere nicht. Die anderen verlassen sich auf die Versprechen-API, deren Arbeit bei der Arbeit mit Stream-Pipes umständlich ist.
Dies ist meine Änderung der akzeptierten Antwort.
quelle
In der oben akzeptierten Antwort ist Folgendes zu beachten: Sie müssen den Durchlauf in der Funktion zurückgeben, wenn Sie Pipe wie verwenden.
fs.createReadStream(<filePath>).pipe(anyUploadFunction())
Andernfalls wird stillschweigend mit dem nächsten fortgefahren, ohne dass ein Fehler ausgegeben wird, oder es wird ein Fehler ausgegeben, der davon
TypeError: dest.on is not a function
abhängt, wie Sie die Funktion geschrieben habenquelle
Für diejenigen, die sich beschweren, dass die, wenn sie die s3-API-Upload-Funktion und eine Null-Byte-Datei verwenden, auf s3 (@ Radar155 und @gabo) landen - ich hatte auch dieses Problem.
Erstellen Sie einen zweiten PassThrough-Stream und leiten Sie einfach alle Daten vom ersten zum zweiten weiter und übergeben Sie den Verweis auf diese Sekunde an s3. Sie können dies auf verschiedene Arten tun - möglicherweise besteht eine schmutzige Methode darin, auf das Ereignis "Daten" im ersten Stream zu warten und dann dieselben Daten in den zweiten Stream zu schreiben - ähnlich wie für das Ereignis "Ende" - einfach aufzurufen die Endfunktion im zweiten Stream. Ich habe keine Ahnung, ob dies ein Fehler in der aws-API, der Version des Knotens oder einem anderen Problem ist - aber es hat das Problem für mich umgangen.
So könnte es aussehen:
quelle
Wenn es jemandem hilft, konnte ich erfolgreich vom Client auf s3 streamen:
https://gist.github.com/mattlockyer/532291b6194f6d9ca40cb82564db9d2a
Der serverseitige Code geht davon aus, dass
req
es sich um ein Stream-Objekt handelt. In meinem Fall wurde er vom Client mit in den Headern festgelegten Dateiinformationen gesendet.Ja, es verstößt gegen die Konvention, aber wenn man sich das Wesentliche ansieht, ist es viel sauberer als alles andere, was ich mit Multer, Busboy usw. gefunden habe.
+1 für Pragmatismus und danke an @SalehenRahman für seine Hilfe.
quelle
Ich verwende KnexJS und hatte ein Problem mit der Streaming-API. Ich habe es endlich behoben, hoffentlich hilft das Folgende jemandem.
quelle
Wenn Sie die Größe des Streams kennen, können Sie den Stream mit minio-js wie folgt hochladen:
quelle