1.web.xml的servlet配置
<servlet>
<servlet-name>downloadServlet</servlet-name> <servlet-class> com.huawei.download.DownloadServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>downloadServlet</servlet-name> <url-pattern>/downloadClient/*</url-pattern> </servlet-mapping>2.DownloadServlet
public class DownloadServlet extends HttpServlet
{@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); }@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String url = req.getRequestURI();
String resFileName = url.substring(url.lastIndexOf("/") + 1, url .length()); String realPath = req.getRealPath("/"); String exeFile = realPath + "download/test.exe"; String kipFile = realPath + "download/test"; PrintWriter out = resp.getWriter(); byte[] bytes = null; OutputStream opts=null; if (DownloadManager.checkFileExist(exeFile, kipFile)) { try {// 如果缓存数组为空或源文件有改动,则重新读取并缓存(注意加锁)
DownloadManager.cheackIsUpdate(exeFile, kipFile);bytes = DownloadManager.getDownloadBytes();
resp.reset();
resp.setContentType("application/x-msdownload"); resp.setHeader("Content-Disposition", "attachment;filename=" + resFileName); opts = resp.getOutputStream(); opts.write(bytes); System.out .println("*************************************************"); System.out.println("* This Is Local Download Server!"); System.out.println("* User IP: " + req.getRemoteAddr()); System.out.println("* Download File Time: " + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .format(new java.util.Date())); System.out .println("*************************************************");} catch (Exception e)
{ System.out.println("read downloadfile error:" + e); } finally { opts.close(); }} else
{ out.println("<center>download file is not exsit!</center>"); } }}3.DownloadManager
public class DownloadManager
{ private static byte[] downloadBytes = null; private static long exeFileLastModified = 0L; private static long kipFileLastModified = 0L;/**
* 重新读取目标文件并缓存 * */ public static void reReadDownloadBytes(String exeFile, String kipFile) throws Exception {File exe = new File(exeFile);
File kip = new File(kipFile); setExeFileLastModified(exe.lastModified()); setKipFileLastModified(kip.lastModified()); BufferedInputStream buffer = null; ByteArrayOutputStream bos = null; try { buffer = new BufferedInputStream(new FileInputStream(exe)); //目标文件exe文件大概300k,一次性读取 int dataSize = 1024*300; byte[] bt = new byte[dataSize]; int len = 0; bos = new ByteArrayOutputStream(); while ((len = buffer.read(bt)) > 0) { bos.write(bt, 0, bt.length); } } catch (Exception e) { throw e; } finally { buffer.close(); bos.close(); }setDownloadBytes(bos.toByteArray());
System.out.println("-------------reReading------------"); System.out.println("-------------Time: " + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .format(new java.util.Date())); }/**
* 检测客户端目标文件是否存在 */ public static boolean checkFileExist(String exeFile, String kipFile) { File exe = new File(exeFile); File kip = new File(kipFile);if (kip.exists() && exe.exists())
{ return true; } return false; }/**
* 检测检测目标文件否更新 * */ public static boolean isFileModified(String exeFile, String kipFile) { File exe = new File(exeFile); File kip = new File(kipFile);long nowExeFileLastModified = exe.lastModified();
long nowKipFileLastModified = kip.lastModified();if ((nowExeFileLastModified != getExeFileLastModified())
|| (nowKipFileLastModified != getKipFileLastModified())) { return true; } return false; }
/**
* 判断是否需要重新读取文件(要加鎖) * 此方法虽然加锁,但是不耗时间 * @throws Exception */ public static synchronized void cheackIsUpdate(String exeFile, String kipFile) throws Exception { if (null == DownloadManager.getDownloadBytes() || DownloadManager.isFileModified(exeFile, kipFile)) { DownloadManager.reReadDownloadBytes(exeFile,kipFile); } }
public static byte[] getDownloadBytes()
{ return downloadBytes; }public static void setDownloadBytes(byte[] downloadBytes)
{ DownloadManager.downloadBytes = downloadBytes; }public static long getExeFileLastModified()
{ return exeFileLastModified; }public static long getKipFileLastModified()
{ return kipFileLastModified; }public static void setExeFileLastModified(long exeFileLastModified)
{ DownloadManager.exeFileLastModified = exeFileLastModified; }public static void setKipFileLastModified(long kipFileLastModified)
{ DownloadManager.kipFileLastModified = kipFileLastModified; }}
4. 请求下载地址
注意:1.缓存下载文件,需要使用静态字节数组保存,样例中使用了两个输出的转换,很重要: 2.注意静态对象修改需要加锁 File f = new File(exeFile); BufferedInputStream buffer = new BufferedInputStream( new FileInputStream(f)); int dataSize = 1024*1024*10; byte[] bt = new byte[dataSize]; int len = 0; resp.reset();resp.setContentType("application/x-msdownload"); resp.setHeader("Content-Disposition", "attachment;filename=" + resFileName); OutputStream out1 = resp.getOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); //判断 while ((len = buffer.read(bt)) > 0) { bos.write(bt, 0, bt.length); //out1.write(bt, 0, len); } //bos.toByteArray()可以缓存 out1.write(bos.toByteArray()); buffer.close(); out1.close(); bos.close();
|