Wie erzwinge ich den Download großer Dateien, ohne zu viel Speicher zu verbrauchen?

8

Ich versuche, große Zip-Dateien für Benutzer bereitzustellen. Wenn zwei gleichzeitige Verbindungen vorhanden sind, verfügt der Server nicht über genügend Arbeitsspeicher (RAM). Ich habe die Speicherkapazität von 300MB auf 4GB erhöht (Dreamhost VPS) und dann hat es funktioniert.

Ich muss viel mehr als zwei gleichzeitige Verbindungen zulassen. Die tatsächlichen 4 GB würden so etwas wie 20 gleichzeitige Verbindungen erlauben (schade).

Nun, der aktuelle Code, den ich benutze, benötigt das doppelte an Speicher und dann die tatsächliche Dateigröße. Das ist sehr schade. Ich möchte etwas wie "Streaming" der Datei an den Benutzer. Also würde ich nicht mehr als das Stück, das den Benutzern serviert wird, zuweisen.

Der folgende Code ist der, den ich in CodeIgniter (PHP-Framework) verwende:

%Vor%

Die force_download-Funktion ist wie folgt (CodeIgniter Standard-Hilfsfunktion):

%Vor%

Ich habe einige auf Chunks basierende Codes ausprobiert, die ich in Google gefunden habe, aber die Datei wurde immer beschädigt geliefert. Wahrscheinlich wegen schlechtem Code.

Könnte mir jemand helfen?

    
Leandro Alves 01.06.2011, 02:13
quelle

5 Antworten

3

Es gibt einige Ideen in diesem Thema . Ich weiß nicht, ob die readfile () Methode Speicher speichert, aber es klingt vielversprechend.

    
King Skippus 01.06.2011, 02:33
quelle
3

Sie senden den Inhalt ($ data) dieser Datei per PHP?

Wenn dies der Fall ist, wird jeder Apache-Prozess, der damit fertig wird, auf die Größe dieser Datei wachsen, da diese Daten zwischengespeichert werden.

Ihre einzige Lösung ist, keine Dateiinhalte / Daten über PHP zu senden und den Benutzer einfach zu einer Download-URL im Dateisystem umzuleiten.

Verwenden Sie einen generierten und eindeutigen Symlink oder einen versteckten Ort.

    
rightstuff 01.06.2011 12:38
quelle
0

Sie können $ data nicht mit ganzen Dateidaten darin verwenden. Versuchen Sie, an diese Funktion nicht den Inhalt der Datei zu übergeben, sondern nur den Pfad. Als nächstes senden Sie alle Header einmal und danach lesen Sie einen Teil dieser Datei mit fread (), echo diesen Chunk, call flush () und wiederholen. Wenn in der Zwischenzeit ein anderer Header gesendet wird, wird die Übertragung schließlich beschädigt.

    
Arek Jablonski 01.06.2011 02:38
quelle
0

Verknüpfen Sie die große Datei mit Ihrem Dokumenten-Root (vorausgesetzt, es handelt sich nicht um eine autorisierte Datei) und lassen Sie Apache damit umgehen. (Auf diese Weise können Sie auch Byte-Bereiche akzeptieren)

    
Petah 01.06.2011 02:42
quelle
0

Fügen Sie Ihre ini_set vor SESSION_START();

hinzu     
Emile Swarts 07.07.2011 11:50
quelle