Java web 中文件下载遇到的缓冲大小问题
刚才自己做一个小例子,就是在android端点击一个button,然后从服务器端下载文件到手机SD卡。结果却遇到了问题,刚开始挺兴奋的,因为自己做的可以下载下来文件了,但是自习看才发现有问题,那就是下载到文件的大小却是0,导出后无法打开,搞不懂,然后不知道怎么搞的过了一会儿,文件大小自己又变化了,下载的一个txt的文件大小恢复正常,而下载的mp3文件却只有198K,如下图:
我的服务端代码如下图:
遇到这么奇葩的问题,我就开始想读取txt那个就成功了,为什么这个却失败了,看了看代码才知道,原来自己读取的方式不一样,在读取txt的时候代码如下;
1 protected void doGet(HttpServletRequest request, 2 HttpServletResponse response) throws ServletException, IOException { 3 4 String path = this.getServletContext().getRealPath("/download/pig.jpg"); 5 String filename = path.substring(path.lastIndexOf("\\") + 1); 6 7 // 这里如果把path.lastIndexOf("\\")中内容改为"/",则下载下来的文件名含有完整路径。 8 // 相当于直接设置为response.setHeader("content-disposition", 9 // "attachment;filename="+ path); 10 11 InputStream in = null; 12 OutputStream out = null; 13 14 response.setHeader("content-disposition", "attachment;filename=" 15 + filename); 16 17 try { 18 in = new FileInputStream(path); 19 20 out = response.getOutputStream(); 21 22 int len = 0; 23 byte buffer[] = new byte[1024]; 24 while ((len = in.read(buffer)) != 0) { 25 26 out.write(buffer, 0, len); 27 } 28 29 } catch (Exception e) { 30 // TODO: handle exception 31 } finally { 32 try { 33 in.close(); 34 out.close(); 35 } catch (Exception e) { 36 // TODO Auto-generated catch block 37 e.printStackTrace(); 38 } 39 } 40 41 }
从上面大家可以看出二者的区别,那就是作为缓冲的byte数组的长度问题,一个是直接固定的1024大小,另一个是自己为了运用一种网上别人写代码的习惯尝试着直接判断流里数据的大小,由此来一次性的生成一个大小刚好的数组来存放数据,事实证明错误恰恰就出在此,按照读取txt文件的方式改变读取mp3文件的代码,发现程序运行正常了。
解释:
因为mp3文件不同于文本文件,MP3格式的歌曲完整的小的一般的也有2,3M大小,转换成字节B的话用来创建数组,值就显得比较大了。应该是在此处造成的内存问题导致出现了这种莫名其妙的错误。
因为自己也是刚学习Java不久,所以很多也只是猜测,没有去研究源码或者看更加深入的书,所以如果大家有什么更好的解释或者说更专业的解释,还望指点一二。让我也能解惑。谢谢啦。
以上随笔内容中均为作者原创,转载请注明博客链接地址。欢迎大家在下面留言,大家一起交流学习。