按字节读取流,byte[] buf = new byte[1024]是固定长度的读取,但是当InputStream 长度超过指定大小的字节后,会造成只读到了一部分,把这个1024换成2024或是更大也只是暂时的。
这时候inputStream.available()这个方法作用就出现了,方法说明是这样的
Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes.
大概的意思是下一次会话会返回一个估计的字节的长度的流,不会阻塞或者跳过,下一次调用可能是同一个线程或另一个线程。一次读取或跳过这么多字节不会阻塞,但可以读取或跳过更少的字节。
问题
一般情况下是可行的
![](https://img.haomeiwen.com/i15292651/49ed42810b16c1dc.png)
某次下载大文件出现内存异常日志里出现了OutOfMemoryError
Caused by: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at com.pingan.pilot.spim.manuscript.controller.AttachmentController.downloadZipAttachment(AttachmentController.java:829)
解决办法
错误源头在这:
![](https://img.haomeiwen.com/i15292651/02962753394cc7b4.png)
所以在body=new byte[inputStream.available()]中
inputStream.available()方法返回的是int,而int的长度是32bit,表示数的范围是-2^31到2^31-1
2^31Byte=2*1024*1024*1024Byte=2GB,按字节读取大文件,2G大小就会到达int的最大值,出现OutOfMemoryError
用分块能避免这个问题,且减少内存消耗
byte[] bytes = new byte[2048];
int len;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
网友评论