用java写了一个下载文件的类,旨在用浏览器下载服务端文件,代码大致如下:
/**
* 文件下载
* @param res
* @param filePath
* @throws UnsupportedEncodingException
*/
public void downloadFile(HttpServletRequest req,HttpServletResponse res,String filePath) throws UnsupportedEncodingException{
if(null == filePath || "".equals(filePath.trim())){
return;
}
filePath = Util.getUTF8(filePath);
res.setCharacterEncoding("UTF-8");
String fileName = URLEncoder.encode(getFileName(filePath), "UTF-8");
res.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
OutputStream os = null;
FileInputStream fis = null;
try {
os = res.getOutputStream();
fis = new FileInputStream(filePath);
byte[] b = new byte[100];
int c;
while((c=fis.read(b))>0){
os.write(b,0,c);
}
os.flush();
os.close();
} catch (IOException e) {
log.error(e);
e.printStackTrace();
}finally{
if(null!=fis){
try {
fis.close();
} catch (IOException e) {
log.error(e);
e.printStackTrace();
}
}
if(null!=os){
try {
os.close();
} catch (IOException e) {
log.error(e);
e.printStackTrace();
}
}
}
}
1.文件名有空格时,空格变为加号
上面的代码调试执行后,用谷歌和IE进行调试下载,内容没有问题,但却发现要下载的文件名中含有空格的时候,空格变成了加号如下图:
添加以下代码,对文件名进行空格替换即可解决:
fileName=fileName.replaceAll("\\+","%20"); //处理空格转为加号的问题
2.下载文件的文件名称乱码
在上面对文件名处理后,发现在谷歌和IE没有问题,而火狐浏览器出现中文乱码:
觉得奇怪,因为看最上面的代码块中,已经进行过UTF-8转换。但知道这是由于对文件名进行编码的问题,于是用以下方式对文件进行编码处理:
if(req.getHeader("User-Agent").toUpperCase().indexOf("MSIE")>0){
fileName = URLEncoder.encode(getFileName(filePath), "UTF-8");
}else{
fileName = new String((getFileName(filePath)).getBytes("UTF-8"),"ISO8859-1");
}
这样处理后,该问题得到解决,也就是我们要指定UTF-8编码的标准,各个浏览器默认的编码标准可能不大一样。
3.下载文件被截段
进行上面两次处理后,谷歌和IE浏览器都已正常,但发现,在火狐浏览器中,因为要下载的文件名中有空格,下载文件被截断了,导致文件后缀被去掉,文件类型无从得知,只知道为“文件”类型,如图:
作为一个严谨的程序员,还是要解决好兼容性的。将上面代码中setHeader方法中的文件名,用字符串包起来即以解决,代码改为如下:
res.setHeader("Content-Disposition", "attachment;fileName=\"" + fileName +"\"");
至此,通过对文件名字符串进行处理,下载文件名空格变加号、乱码、被截断问题都得以解决。