本文实例为大家分享了java断点续传下载的代码,供大家参考,具体内容如下
1. Java代码
//实现文件下载功能 public String downloadFile(){ File dir = new File(filepath);//获取文件路劲 if(!dir.exists()) { System.out.println(\"文件路径错误\"); log.debug(\"文件路径错误\"); return \"failed\";// 判断文件或文件夹是否存在 } File downloadFile = new File(dir, filename);//在指定目录下查找文件 if(!downloadFile.isFile()){ System.out.println(\"文件不存在\"); log.debug(\"文件不存在\"); return \"failed\";// 判断文件或文件夹是否存在 } try { downloadFileRanges(downloadFile); } catch(ClientAbortException e){ System.out.println(\"连接被终止\"); log.debug(\"连接被终止\"); } catch (IOException e) { e.printStackTrace(); } return null; } private void downloadFileRanges(File downloadFile) throws IOException { // 要下载的文件大小 long fileLength = downloadFile.length(); // 已下载的文件大小 long pastLength = 0; // 是否快车下载,否则为迅雷或其他 boolean isFlashGet = true; // 用于记录需要下载的结束字节数(迅雷或其他下载) long lenEnd = 0; // 用于记录客户端要求下载的数据范围字串 String rangeBytes = request.getHeader(\"Range\"); //用于随机读取写入文件 RandomAccessFile raf = null; OutputStream os = null; OutputStream outPut = null; byte b[] = new byte[1024]; // 如果客户端下载请求中包含了范围 if (null != rangeBytes) { // 返回码 206 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); rangeBytes = request.getHeader(\"Range\").replaceAll(\"bytes=\", \"\"); // 判断 Range 字串模式 if (rangeBytes.indexOf(\'-\') == rangeBytes.length() - 1) { // 无结束字节数,为快车 isFlashGet = true; rangeBytes = rangeBytes.substring(0, rangeBytes.indexOf(\'-\')); pastLength = Long.parseLong(rangeBytes.trim()); } else { // 迅雷下载 isFlashGet = false; String startBytes = rangeBytes.substring(0, rangeBytes.indexOf(\'-\')); String endBytes = rangeBytes.substring( rangeBytes.indexOf(\'-\') + 1, rangeBytes.length()); // 已下载文件段 pastLength = Long.parseLong(startBytes.trim()); // 还需下载的文件字节数(从已下载文件段开始) lenEnd = Long.parseLong(endBytes); } } // 通知客户端允许断点续传,响应格式为:Accept-Ranges: bytes response.setHeader(\"Accept-Ranges\", \"bytes\"); // response.reset(); // 如果为第一次下载,则状态默认为 200,响应格式为: HTTP/1.1 200 ok if (0 != pastLength) { // 内容范围字串 String contentRange = \"\"; // 响应格式 // Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]||[文件的总大小] if (isFlashGet) { contentRange = new StringBuffer(\"bytes\") .append(new Long(pastLength).toString()).append(\"-\") .append(new Long(fileLength - 1).toString()) .append(\"/\").append(new Long(fileLength).toString()) .toString(); } else { contentRange = new StringBuffer(rangeBytes).append(\"/\") .append(new Long(fileLength).toString()).toString(); } response.setHeader(\"Content-Range\", contentRange); } String fileName = getDownloadChineseFileName(filename); response.setHeader(\"Content-Disposition\", \"attachment;filename=\" + fileName + \"\"); // 响应的格式是: response.setContentType(\"application/octet-stream\"); response.addHeader(\"Content-Length\", String.valueOf(fileLength)); try { os = response.getOutputStream(); outPut = new BufferedOutputStream(os); raf = new RandomAccessFile(downloadFile, \"r\"); // 跳过已下载字节 raf.seek(pastLength); if (isFlashGet) { // 快车等 int n = 0; while ((n = raf.read(b, 0, 1024)) != -1) { outPut.write(b, 0, n); } } else { // 迅雷等 while (raf.getFilePointer() < lenEnd) { outPut.write(raf.read()); } } outPut.flush(); } catch (IOException e) { /** * 在写数据的时候 对于 ClientAbortException 之类的异常 * 是因为客户端取消了下载,而服务器端继续向浏览器写入数据时, 抛出这个异常,这个是正常的。 尤其是对于迅雷这种吸血的客户端软件。 * 明明已经有一个线程在读取 bytes=1275856879-1275877358, * 如果短时间内没有读取完毕,迅雷会再启第二个、第三个。。。线程来读取相同的字节段, 直到有一个线程读取完毕,迅雷会 KILL * 掉其他正在下载同一字节段的线程, 强行中止字节读出,造成服务器抛 ClientAbortException。 * 所以,我们忽略这种异常 */ } finally { if(outPut != null) { outPut.close(); } if(raf != null) { raf.close(); } } } private String getDownloadChineseFileName(String paramName) { String downloadChineseFileName = \"\"; try { downloadChineseFileName = new String(paramName.getBytes(\"GBK\"), \"ISO8859-1\"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return downloadChineseFileName; } public String getFilepath() { return filepath; } public void setFilepath(String filepath) { this.filepath = filepath; } public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename; } public HttpServletRequest getRequest() { return request; } public HttpServletResponse getResponse() { return response; }
2. struts部分
3. jsp部分
本文地址:https://www.stayed.cn/item/21629
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我