2012-08-31 59 views
0

即時發送視頻,互聯網服務和工程確定與小於10MB的視頻,如果視頻是大約12MB給我的OutOfMemoryError:的OutOfMemoryError ByteArrayOutputStream發送大文件,WS

這是我的代碼:

FileInputStream fileInputStream = new FileInputStream(fichero); 

       int bytesAvailable = fileInputStream.available(); 
       int maxBufferSize = 1024 * 1024 * 2; 
       int bufferSize = Math.min(bytesAvailable, maxBufferSize); 
       byte[] buffer = new byte[bufferSize]; 

       int bytesRead = fileInputStream.read(buffer, 0, bufferSize); 

       while (bytesRead > 0) { 
        dos.write(buffer, 0, bufferSize); 
        bytesAvailable = fileInputStream.available(); 
        bufferSize = Math.min(bytesAvailable, maxBufferSize); 
        // nuevos 
        byte byt[] = new byte[bufferSize]; 
        fileInputStream.read(byt); 

        // nuevos 
        bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
        // esto es nuevo 
        dos.write(buffer, 0, bufferSize); 
        // ya no es nuevo 
       } 

我認爲這是因爲我緩衝所有的視頻,但我不知道如何發送這個緩衝區沒有saviing。

這是堆棧錯誤:

08-31 08:54:20.925: E/AndroidRuntime(18476): Caused by: java.lang.OutOfMemoryError 
08-31 08:54:20.925: E/AndroidRuntime(18476): at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91) 
08-31 08:54:20.925: E/AndroidRuntime(18476): at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:216) 
08-31 08:54:20.925: E/AndroidRuntime(18476): at org.apache.harmony.luni.internal.net.www.protocol.http.RetryableOutputStream.write(RetryableOutputStream.java:60) 
08-31 08:54:20.925: E/AndroidRuntime(18476): at java.io.DataOutputStream.write(DataOutputStream.java:99) 
08-31 08:54:20.925: E/AndroidRuntime(18476): at com.reparalia.movilidad.AdjuntarFicheros$SubeFichero.doInBackground(AdjuntarFicheros.java:702) 
08-31 08:54:20.925: E/AndroidRuntime(18476): at com.reparalia.movilidad.AdjuntarFicheros$SubeFichero.doInBackground(AdjuntarFicheros.java:1) 

的702行是dos.write(緩衝液,0,緩衝區大小);

有什麼辦法可以發送視頻?謝謝

回答

1

而不是寫代碼來流自行復制的,你可以嘗試使用庫類來做到這一點。

在番石榴,ByteStreams類是可用的。如果您是Commons IO類人員,則有IOUtils

在IOUtils,您的代碼會是這個樣子:

FileInputStream fileInputStream = new FileInputStream(fichero); 
OutputStream dos = ... 
IOUtils.copy(fileInputStream, dos); 

我已經離開了必要的異常處理和流關閉。

+0

你能給我一個例子使用ioutils嗎?我不知道我該怎麼做。謝謝 – rbrlnx

+0

我用ioutils的例子更新了我的答案。 –

+0

這將我複製到dos 0字節:S – rbrlnx

3

ByteArrayOutputStream通過分配默認情況下分配32字節或構造函數指定的內存量來開始。當緩衝區被填滿後,ByteArrayOutputStream雙擊緩衝區的大小。對於大型物體,這可能是一個真正的問題。你最好的選擇是要麼

  1. 利用構造函數指定的緩衝區大小,或
  2. 擴展ByteArrayOutputStream和覆蓋寫入方法,以便重新分配自己的視頻流更有利。
1

這發生,因爲 - 如果既沒有setFixedLengthStreamingMode(INT)當主體長度是預先已知的,也不setChunkedStreamingMode(INT)被設置。 在這種情況下,HttpURLConnection被強制在發送之前緩衝內存中的完整請求主體,浪費(可能耗盡)堆並增加延遲。 中的鏈接很好解釋 - http://developer.android.com/reference/java/net/HttpURLConnection.html

以下行請添加到您的代碼 - HttpUrlConnectionObject。 setChunkedStreamingMode(maxBufferSize); 默認系統值設置0 HttpUrlConnectionObject.setChunkedStreamingMode(0);

這適用於我。