问题
im sending videos to webservice and works ok with videos less than 10MB, if the video is about 12MB give me outofmemoryerror:
This is my code:
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
}
I think it is because im buffering all video, but i dont know how to send this without saviing in buffer.
This is the stack error:
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)
The 702 line is dos.write(buffer, 0, bufferSize);
There are any way to send the video?Thanks
回答1:
ByteArrayOutputStream
starts out by allocating either 32 bytes or a constructor-specified amount of memory by default. When that buffer has been filled-up, ByteArrayOutputStream
doubles the size of the buffer. For large objects, this can be a real problem. Your best alternative is to either
- Make use of the constructor-specified buffer size, or
- Extend
ByteArrayOutputStream
and override the write methods so that reallocation is more advantageous for your stream.
回答2:
Instead of writing the code to copy the stream yourself, you might try using a library class to do it.
In Guava, the ByteStreams class is available. If you're a Commons IO kind of person, there's IOUtils.
In IOUtils, your code would look something like this:
FileInputStream fileInputStream = new FileInputStream(fichero);
OutputStream dos = ...
IOUtils.copy(fileInputStream, dos);
I've left out the necessary exception handling and stream closing.
回答3:
This is happening because - If neither setFixedLengthStreamingMode(int) when the body length is known in advance, nor setChunkedStreamingMode(int) is set. In that case HttpURLConnection is forced to buffer the complete request body in memory before it is transmitted, wasting (and possibly exhausting) heap and increasing latency. Very well explained in the link - http://developer.android.com/reference/java/net/HttpURLConnection.html
Kindly add below line to your code - HttpUrlConnectionObject.setChunkedStreamingMode(maxBufferSize); for default system value set 0 HttpUrlConnectionObject.setChunkedStreamingMode(0);
This works for me.
来源:https://stackoverflow.com/questions/12210322/outofmemoryerror-bytearrayoutputstream-sending-large-file-to-ws