import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.net.URLEncoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 功能说明: 下载文件Utils<br>
* 系统版本: v1.0 <br>
* 开发人员: liuyh@hundsun.com <br>
* 开发时间: 2011-5-9
* <br>
*/
public class DownLoadUtils {
private static final BizLog log = LoggerFactory.getBizLogger(DownLoadUtils.class);
/**
* 默认为10K
*/
private static int bufferSize = 10240;
/**
* 默认为UTF-8
*/
private String charset = "UTF-8";
/**
* 默认为ISO8859-1
*/
private String fileNameCharset = "ISO8859-1";
private DownLoadUtils(){}
/**
* 单例持有内部类
*/
static class DownLoadUtilsHolder {
static DownLoadUtils instance = new DownLoadUtils();
}
public static DownLoadUtils getInstance() {
return DownLoadUtilsHolder.instance;
}
/**
* 下载文件
* @param aResponse
* 输出response
* @param aFilePath
* 服务器上的文件的全路径
* @param aFileName
* 客户下载时的文件的默认名称
* @throws Exception
* NullPointerException 参数为空
* FileNotFoundException 服务器文件不存在<br>
* IOException 下载IO异常
*/
public void download(HttpServletResponse response, String filePath, String fileName) throws Exception {
doDownload(response, filePath, fileName);
}
public static void doDownload(HttpServletResponse response, String filePath, String fileName) throws Exception {
OutputStream servletOut = null;
BufferedInputStream in = null;
// 系统参数缓存
BizframeParamterCache paramCache = BizframeParamterCache.getInstance();
// 存放项目文档的根路径
String sysPath = paramCache.getValue(TcmpConstants.SYSPARAM_UPLOADFILEPATH);
try {
File file = new File(filePath);
if(!file.exists()){//判断路径不存在时
file = new File(sysPath + File.separator + filePath);
}
if(StringUtil.isBlank(fileName)){
fileName=file.getName();
}
FileInputStream fis = new FileInputStream(file);
long totalsize = fis.available();
in = new BufferedInputStream(fis);
response.reset();
fileName = filterFileName(fileName);
response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
response.addHeader("Content-Length", String.valueOf(totalsize));
response.setContentType("application/octet-stream;charset=UTF-8");
servletOut = response.getOutputStream();
byte[] temp = new byte[bufferSize];
int size = 0;
while ((size = in.read(temp)) != -1) {
servletOut.write(temp, 0, size);
}
servletOut.flush();
} catch (FileNotFoundException e) {
log.error("下载文件找不到, filePath = " + filePath, e);
throw new TcmpException(TcmpException.ERROR_ATTACH_NOTFOUND, new Object[0]);
}
catch (SocketException e) {
log.error("下载文件时socket异常, filePath = " + filePath);
} catch (Exception e) {
log.error("下载文件时出错, filePath = " + filePath, e);
throw new TcmpException(TcmpException.ERROR_ATTACH_DOWNLOAD, new Object[0]);
} finally {
try {
if (servletOut != null) {
servletOut.close();
}
if (in != null)
in.close();
}
catch (Exception e) {
log.error("下载文件时关闭资源发生IO异常, filePath = " + filePath, e);
throw new TcmpException(TcmpException.ERROR_ATTACH_DOWNLOAD, new Object[0]);
}
}
try
{
if (servletOut != null) {
servletOut.close();
}
if (in != null)
in.close();
}
catch (Exception e) {
log.error("下载文件时关闭资源发生IO异常, filePath = " + filePath, e);
throw new TcmpException(TcmpException.ERROR_ATTACH_DOWNLOAD, new Object[0]);
}
}
/**
* 导出文件【解决 不同浏览器 不同应用服务器系统 导出文件名乱码】
* @param request 通过request获取浏览器类型
* @param response
* @param filePath 文件路径
* @param fileName 文件名称
* @throws Exception
* @author peiyf08776
*/
public static void doDownload(HttpServletRequest request,HttpServletResponse response, String filePath, String fileName) throws Exception {
OutputStream servletOut = null;
BufferedInputStream in = null;
// 系统参数缓存
BizframeParamterCache paramCache = BizframeParamterCache.getInstance();
// 存放项目文档的根路径
String sysPath = paramCache.getValue(TcmpConstants.SYSPARAM_UPLOADFILEPATH);
try {
File file = new File(filePath);
if(!file.exists()){
file = new File(sysPath + File.separator + filePath);
}
FileInputStream fis = new FileInputStream(file);
long totalsize = fis.available();
in = new BufferedInputStream(fis);
response.reset();
response.addHeader("Content-Disposition", "attachment;" + encodeFileName(request,fileName));
response.addHeader("Content-Length", String.valueOf(totalsize));
response.setContentType("application/octet-stream;charset=UTF-8");
servletOut = response.getOutputStream();
byte[] temp = new byte[bufferSize];
int size = 0;
while ((size = in.read(temp)) != -1) {
servletOut.write(temp, 0, size);
}
servletOut.flush();
} catch (FileNotFoundException e) {
log.error("下载文件找不到, filePath = " + filePath, e);
throw new TcmpException(TcmpException.ERROR_ATTACH_NOTFOUND);
} catch (SocketException e) {
// 若为socket异常,则不抛出异常
log.error("下载文件时socket异常, filePath = " + filePath);
} catch (Exception e) {
log.error("下载文件时出错, filePath = " + filePath, e);
throw new TcmpException(TcmpException.ERROR_ATTACH_DOWNLOAD);
} finally {
try {
if (servletOut != null) {
servletOut.close();
}
if (in != null) {
in.close();
}
} catch (Exception e) {
log.error("下载文件时关闭资源发生IO异常, filePath = " + filePath, e);
throw new TcmpException(TcmpException.ERROR_ATTACH_DOWNLOAD);
}
}
}
/**
* 下载文件 根据路径下载
* @param response 输出流
* @param path 文件路径
* @param fileName 文件名称
* @param fileType 文件类型
* @throws BizBussinessException
* @author zhudz18200
*/
public static void doDownload(HttpServletResponse response,String path, String fileName, String fileType)
throws BizBussinessException {
File fileForRead = new File(path + fileName);
if (!fileForRead.exists()) {
throw new BizframeException(BizframeException.ERROR_DEFAULT, "要下载的文件不存在!");
}
try {
response.reset();
response.setContentType("application/" + fileType);
String downFileName=new String(fileName.getBytes("gb2312"),"ISO8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\""
+ downFileName + "\"");
ServletOutputStream out = response.getOutputStream();
FileInputStream fis = new FileInputStream(fileForRead);
byte[] data=new byte[1024];
int temp = -1;
while((temp = fis.read(data))!= -1){
out.write(data, 0, temp);
out.flush();
}
fis.close();
out.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new BizframeException(BizframeException.ERROR_DEFAULT, "下载失败!");
}
}
/**
* 根据不同浏览器编码导出文件名称
* @param request
* @param fileName
* @return
* @author peiyf08776
*/
private static String encodeFileName(HttpServletRequest request,String fileName){
String userAgent = request.getHeader("User-Agent");
String rtn = "";
try {
String new_filename = URLEncoder.encode(fileName, "UTF-8");
// 如果没有UA,则默认使用IE的方式进行编码
rtn = "filename=\"" + new_filename + "\"";
if (userAgent != null) {
userAgent = userAgent.toLowerCase();
// IE浏览器,只能采用URLEncoder编码
if (userAgent.indexOf("msie") != -1) {
rtn = "filename=\"" + new_filename + "\"";
}
// Safari浏览器,只能采用ISO编码的中文输出
else if (userAgent.indexOf("safari") != -1 && userAgent.indexOf("chrome") == -1) {
rtn = "filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + "\"";
// 其他浏览器
}else{
rtn = "filename=" + new_filename + ";filename*=utf-8''" + new_filename;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return rtn;
}
/**
* 替换掉文件名中非法的字符,如;,等。
* @param fileName 文件名
* @return 替换后的文件名
*/
public static String filterFileName(String fileName){
if(fileName == null){
return fileName;
}
return fileName.replaceAll(";", "、") //如果文件名中包含;号,则下载时文件名会被截断到;号位置
.replaceAll(";", "、")
.replaceAll(",", ","); //如果文件名中包含,号,谷歌浏览器会认识是恶意描述,IE正常
}
/**
* 设置下载缓冲区大小
* @param bufferLength
* 默认为10K
* @return
*/
public DownLoadUtils setBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
return this;
}
/**
* 设置下载字符集
* @param charset
* 默认为UTF-8
* @return
*/
public DownLoadUtils setCharset(String charset) {
this.charset = charset;
return this;
}
/**
* 下载文件名字符集
* content 根据内容下载
* @param fileNameCharset
* 默认为ISO8859-1
* @return
*/
public DownLoadUtils setFileNameCharset(String fileNameCharset) {
this.fileNameCharset = fileNameCharset;
return this;
}
public static void contentDownload(HttpServletResponse response, String content, String fileName) throws Exception {//设置响应的字符集
response.setCharacterEncoding("utf-8");
//设置响应内容的类型
response.setContentType("text/plain");
//设置文件的名称和格式
response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
BufferedOutputStream buff = null;
ServletOutputStream outStr = null;
try {
outStr = response.getOutputStream();
buff = new BufferedOutputStream(outStr);
buff.write(content.getBytes("UTF-8"));
buff.flush();
buff.close();
} catch (Exception e) {
} finally {try {
buff.close();
outStr.close();
} catch (Exception e) {
}
}
}
}