很简单的web文件下载,只有一个servlet,用户请求的量比较大。调试发现,当下载提示框弹出后,在向response.getOutputstream().write()的时候,暂停了。
。
byte[] buffer = new byte[SIZE];
byteread = bis.read(buffer);
while (-1 != byteread) {
System.out.println("count="+count++);
System.out.println("aaaaaaa");
bos.write(buffer, 0, byteread); //A
System.out.println("bbbbbbb");
byteread = bis.read(buffer);
}
bos.flush();
bos.close();
代码没有问题,文件可以下载,仅仅 当弹出下载对话框后,我没有立即去点击“下载” 或者“保存” 按钮,就发现
servlet 阻塞在上面代码的A处,直到我点击“下载”按钮或者“保存”按钮,才继续执行,并释放掉servlet所用的线程。
如果,我一直不点击,后台就会报“Connection reset by peer: socket write error”异常。
问题是,我原来总以为,弹出框体后,servlet线程,就执行完毕了,现在居然发现是这样子的,难道 一弹出下载框,servlet就会被阻塞,还是我的代码有问题呢??请各位大大讲解一下。
InputStream bis = null;
OutputStream bos = null;
try {
ServletOutputStream sos = response.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(filePath));
bos = new BufferedOutputStream(sos);
byte[] buffer = new byte[4096];
// 清空response
response.reset();
response.setContentType("application/octet-stream;charset=gbk");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.addHeader("Content-Length", "" + (int)new File(filePath).length());
response.flushBuffer();
response.setStatus(response.SC_OK);
System.out.println("文件读取开始");
int byteread = 0;
byteread = bis.read(buffer);
while (-1 != byteread) {
System.out.println("aaaaaaa");
bos.write(buffer, 0, byteread);//弹出下载框后,就会阻塞在这里
System.out.println("bbbbbbb");
byteread = bis.read(buffer);
}
bos.flush();
bos.close();
} catch (Exception e) {
System.out.println("error:" + fileName);
e.printStackTrace();
} finally {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
}
System.out.println(fileName + "文件下载完毕.");
。
byte[] buffer = new byte[SIZE];
byteread = bis.read(buffer);
while (-1 != byteread) {
System.out.println("count="+count++);
System.out.println("aaaaaaa");
bos.write(buffer, 0, byteread); //A
System.out.println("bbbbbbb");
byteread = bis.read(buffer);
}
bos.flush();
bos.close();
代码没有问题,文件可以下载,仅仅 当弹出下载对话框后,我没有立即去点击“下载” 或者“保存” 按钮,就发现
servlet 阻塞在上面代码的A处,直到我点击“下载”按钮或者“保存”按钮,才继续执行,并释放掉servlet所用的线程。
如果,我一直不点击,后台就会报“Connection reset by peer: socket write error”异常。
问题是,我原来总以为,弹出框体后,servlet线程,就执行完毕了,现在居然发现是这样子的,难道 一弹出下载框,servlet就会被阻塞,还是我的代码有问题呢??请各位大大讲解一下。
InputStream bis = null;
OutputStream bos = null;
try {
ServletOutputStream sos = response.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(filePath));
bos = new BufferedOutputStream(sos);
byte[] buffer = new byte[4096];
// 清空response
response.reset();
response.setContentType("application/octet-stream;charset=gbk");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.addHeader("Content-Length", "" + (int)new File(filePath).length());
response.flushBuffer();
response.setStatus(response.SC_OK);
System.out.println("文件读取开始");
int byteread = 0;
byteread = bis.read(buffer);
while (-1 != byteread) {
System.out.println("aaaaaaa");
bos.write(buffer, 0, byteread);//弹出下载框后,就会阻塞在这里
System.out.println("bbbbbbb");
byteread = bis.read(buffer);
}
bos.flush();
bos.close();
} catch (Exception e) {
System.out.println("error:" + fileName);
e.printStackTrace();
} finally {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
}
System.out.println(fileName + "文件下载完毕.");
问题不是服务器端,你还是木搞懂,是浏览器端。火狐的缺省缓存大,也就是它在等你点击下载的时候,可以先把服务器端想发送过来的数据全部缓存起来。
IE的缺省缓存小,比如只有4K(只是比如),那么它在等你点击下载的时候,4K空间早就满了,服务器端再想发送数据,这边就不接收了,那么服务器端就阻塞在发送那里了。