来自文件 或 网络的InputStream数据量可能很大,如果用流的大小申请byte[],可能内存不足报错。
解决方案:分段读取
InputStream的方法int available()返回本次可读取的流的大小。如果可读大小大于缓冲大小,那么每次只读缓冲大小的数据,读n次后再读余下的
,如果可读数小于缓冲大小,那么读全部可读大小。
如:
public static final int MAX_BUFFER = 1024*512;//512k,可以调小,太大会内存不足
1 void save_to_file(InputStream is, long fileSize) throws IOException { 2 File file = new File(Downloader.FILE_PATH, mFileName); 3 FileOutputStream fos = new FileOutputStream(file, true); 4 long sz = 0; 5 byte buffer[] = new byte[Downloader.MAX_BUFFER]; 6 7 while (sz < fileSize && networkConnected) {//当读取总数小于fileSize且有网络连接 8 int available = is.available();//可以读出的数据大小。 9 if (available > Downloader.MAX_BUFFER ) {//如果可读大小大于缓冲大小,那么每次只读缓冲大小的数据,读n次后再读余下的。 10 int cx = available / Downloader.MAX_BUFFER; 11 int readed = 0; 12 for (int i = 0; i < cx; i++) { 13 readed = is.read(buffer, 0, Downloader.MAX_BUFFER ); 14 sz += readed; 15 fos.write(buffer, 0, Downloader.MAX_BUFFER ); 16 fos.flush(); 17 publishProgress(sz * 100 / fileSize); 18 } 19 readed = is.read(buffer,0,available - cx * Downloader.MAX_BUFFER); 20 sz += readed; 21 fos.write(buffer, 0, readed); 22 fos.flush(); 23 publishProgress(sz * 100 / fileSize); 24 System.out.println("available = " + available + " readed = " + readed); 25 26 }else{ 27 //如果可读数小于缓冲大小,那么读全部可读大小。 28 int readed = is.read(buffer, 0, available); 29 System.out.println("available = " + available + " readed = " + readed); 30 sz += readed; 31 fos.write(buffer, 0, available); 32 fos.flush(); 33 publishProgress(sz * 100 / fileSize); 34 } 35 } 36 fos.close(); 37 38 /* 39 * File file = new File(mFilePath,mFileName); FileOutputStream fos = new 40 * FileOutputStream(file,true); 41 * 42 * int available = -1; long sz = 0; while (sz < fileSize ) { available = 43 * is.available(); byte data[] = new byte[available];//产生大量内存泄漏 sz += 44 * is.read(data); fos.write(data); fos.flush(); publishProgress(sz * 45 * 100/fileSize ); } fos.close(); System.gc(); 46 */