0

我将视频发送到网络服务,并且可以处理小于 10MB 的视频,如果视频大约 12MB,给我内存不足错误:

这是我的代码:

 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
                }

我认为这是因为我正在缓冲所有视频,但我不知道如何在不保存缓冲区的情况下发送它。

这是堆栈错误:

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(buffer, 0, bufferSize);

有什么方法可以发送视频吗?谢谢

4

3 回答 3

3

ByteArrayOutputStream首先分配 32 字节或默认情况下构造函数指定的内存量。当该缓冲区被填满时,缓冲区的大小ByteArrayOutputStream 加倍。对于大型物体,这可能是一个真正的问题。你最好的选择是

  1. 使用构造函数指定的缓冲区大小,或者
  2. 扩展ByteArrayOutputStream和覆盖写入方法,以便重新分配对您的流更有利。
于 2012-11-28T14:24:12.023 回答
1

您可以尝试使用库类来完成,而不是自己编写代码来复制流。

在 Guava 中,可以使用ByteStreams类。如果您是 Commons IO 类型的人,则可以使用 IOUtils

在 IOUtils 中,您的代码将如下所示:

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

我省略了必要的异常处理和流关闭。

于 2012-08-31T07:34:36.603 回答
1

发生这种情况是因为 - 如果在预先知道主体长度时既没有setFixedLengthStreamingMode(int) ,也没有设置setChunkedStreamingMode(int)。在这种情况下,HttpURLConnection 被迫在传输之前将完整的请求正文缓冲在内存中,从而浪费(并且可能耗尽)堆并增加延迟。链接中很好地解释了 - http://developer.android.com/reference/java/net/HttpURLConnection.html

请在您的代码中添加以下行 - HttpUrlConnectionObject。setChunkedStreamingMode(maxBufferSize) ; 默认系统值设置为 0 HttpUrlConnectionObject.setChunkedStreamingMode(0);

这对我有用。

于 2014-06-09T08:50:03.883 回答