昨天同事要我帮助另一个女同事完成上传用户头像和下载用户头像的后台功能,今早测的时候发现:
通过IE,在地址栏输入下载图片的url没有报错,而通过同事做的桌面客户端(VC++)发来的请求却报
2009-10-23 10:52:11 org.apache.catalina.core.ApplicationContext log
信息: ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error
这是什么原因?
网上google了一下,看到该帖子:http://www.programfan.com/club/showpost.asp?id=27999
其中:
我把你的代码拷过来,又写了一个客户端,试了一下,没问题,能用,只是:
byte[] zijie=new byte[1024];
while(input.read(zijie)>0)
{
output.write(zijie);
output.flush();
}
要注意最后一次读到的有可能是不满的,所以不能把整个zijie写出去,要用
output.write(zijie,0,len);
在循环外定义:
int len=0;
while((len=input.read(zijie))>0){
...
}
也就是读到多少写多少,否则最后一次是会把上一次的残留也写出去的。
另外就是虽然没问题能运行,但还是要把关流的代码写在finally里比较安全。
原来的代码是:后台直接根据文件路径获取到流返回:
FileInputStream resultInputStream = new FileInputStream(file) ; //取出目标文件
后来改为:
FileInputStream is= new FileInputStream(file) ; //取出目标文件
HttpServletResponse response= ServletActionContext.getResponse();
FileOutputStream fos = null;
try {
String descFileName = ServletActionContext
.getServletContext().getRealPath("/") + "/uploadfiles/" + fileName;
fos = new FileOutputStream(descFileName);
byte[] bs=new byte[1024];
int len=0;
while((len=is.read(bs))>0){
fos.write(bs,0,len);
fos.flush();
}
resultInputStream = new FileInputStream(descFileName);
response.reset();
File fileSize = new File(descFileName);
response.setHeader("Content-Length", Long.toString(fileSize.length()));
} catch (Exception e) {
return null;
}
return resultInputStream;
也有的人说是没有reset()的原因,但是我不在项目的目录下临时存一个文件作为中介,依然会报该错误,只好这样如此处理。但是不知为何在中间加了一层就不报错了呢?
貌似我对打开流没做关闭处理哦,唉!