2010-12-15 18 views
2

Ich bekomme manchmal eine OutOfMemoryError beim Posten einer großen Datei in Android. Dies ist der Code, den ich verwende. Mache ich etwas falsch?Veröffentlichen einer großen Datei in Android

HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
con.setRequestMethod("POST"); 
con.setDoInput(true); 
con.setDoOutput(true); 
ostream = new DataOutputStream(con.getOutputStream()); 
byte[] buffer = new byte[1536]; 
int count; 
while ((count = fileInput.read(buffer)) != -1) { 
    ostream.write(buffer, 0, count); // This sometimes causes OutOfMemoryError 
} 
ostream.flush(); 

Würde Aufruf ostream.flush() innerhalb der while Schleife etwas Gutes tun?

+1

Vielleicht verwenden Sie zu viel Speicher – Falmarri

+0

Wie kann ich weniger verwenden, um dies zu tun? – hpique

+0

versuchen Sie, Ihre Puffergröße zu reduzieren. – Ramp

Antwort

4

Wenn Sie es so machen, muss der gesamte POST im Speicher gepuffert werden. Dies liegt daran, dass der Content-Length-Header zuerst gesendet werden muss.

Stattdessen denke ich, dass Sie die Apache HTTP-Bibliotheken verwenden möchten, einschließlich FileEntity. Dadurch kann die Länge vor dem Lesen der Datei ermittelt werden. Sie können this answer als Ausgangspunkt verwenden. Aber der zweite Parameter für den FileEntity-Konstruktor sollte ein Mime-Typ sein (wie image/png, text/html, etc.).

+0

Danke Matthew. Ist dieses POST-Verhalten irgendwo dokumentiert? In meinem speziellen Fall kenne ich die Inhaltslänge vorher nicht, da sie im Handumdrehen codiert wird, aber ich werde trotzdem in FileEntity nachsehen. – hpique

+0

@hgpc, es ist grundlegend, wie HTTP funktioniert. Header gehen immer vor der Anfrage oder Antwort. Der Server kann entweder den Header "Content-Length" verwenden (empfohlen) oder die Verbindung am Ende der Antwort trennen. Der Client muss jedoch 'Content-Length' verwenden, da er auf der Leitung bleibt, bis er die Antwort erhält. Siehe hierzu [Beispiel POST-Sitzung] (http://www.jmarshall.com/easy/http/#postmethod). –

+0

@hgpc, in was wird es kodiert? –

2

HTTP-Verbindung ist in Ordnung, aber HTTPS wird Out-of-Memory-Fehler auslösen, weil es einen Fehler in HttpsURLConnectionImpl.java in Android 2.3.4 (auf meinem Tablet verifiziert), und es ist in Android 4.1 behoben (Ich habe die Quelle überprüft Code).

Übrigens sollte er vermeiden, die gesamten POST-Daten im RAM durch Hinzufügen von "con.setChunkedStreamingMode (0);" unmittelbar nach "con.setDoOutput (true);" Erklärung.

+0

setChunkedStreamingMode habe keine Änderung mit mir, danke – vuhung3990

Verwandte Themen