Java编程实现服务器端支持断点续传的方法(可支持快车、迅雷)
程序员文章站
2024-03-07 23:04:39
本文实例讲述了java编程实现服务器端支持断点续传的方法。分享给大家供大家参考,具体如下:
大家知道tomcat之流对静态资源可以实现断点续传支持,但是如果是一个被控制的...
本文实例讲述了java编程实现服务器端支持断点续传的方法。分享给大家供大家参考,具体如下:
大家知道tomcat之流对静态资源可以实现断点续传支持,但是如果是一个被控制的流,如有权限控制,或下载地址仅是个代理的时候,这时候需要自己实现断点续传的支持,小弟不才,这里提供基本断点续传[a-,-b,a-b]的简单实现,经验证,可支持迅雷7和火狐的多次断点续传。现贴出代码,大家共同分享:
servlet
import java.io.bufferedoutputstream; import java.io.file; import java.io.ioexception; import java.io.randomaccessfile; import java.io.unsupportedencodingexception; import java.net.uri; import java.net.urisyntaxexception; import java.net.urldecoder; import javax.servlet.servletexception; import javax.servlet.servletoutputstream; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import com.bsteel.cloud.storage.servlet.base.baseservlet; import com.bsteel.cloud.storage.utils.fileutil; /** * 文件下载(支持断点续传【迅雷\快车\旋风\firefox\chrome】) * @author jdkleo * */ public class fileioservlet extends baseservlet { private static final long serialversionuid = 1l; @override protected void doget(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception { this.dopost(req, resp); } @override protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception{ download(request,response); } /** * 文件下载 * @param request * @param response * @throws unsupportedencodingexception */ private void download(httpservletrequest request,httpservletresponse response) throws unsupportedencodingexception { file downloadfile = getfile(request); long pos = fileutil.headersetting(downloadfile, request, response); // log.info("跳过"+pos); servletoutputstream os = null; bufferedoutputstream out = null; randomaccessfile raf = null; byte b[] = new byte[1024];//暂存容器 try { os = response.getoutputstream(); out = new bufferedoutputstream(os); raf = new randomaccessfile(downloadfile, "r"); raf.seek(pos); try { int n = 0; while ((n = raf.read(b, 0, 1024)) != -1) { out.write(b, 0, n); } out.flush(); } catch(ioexception ie) { } } catch (exception e) { log.error(e.getmessage(), e); } finally { if (out != null) { try { out.close(); } catch (ioexception e) { log.error(e.getmessage(), e); } } if (raf != null) { try { raf.close(); } catch (ioexception e) { log.error(e.getmessage(), e); } } } } private file getfile(httpservletrequest request) throws unsupportedencodingexception { string uristr = request.getparameter("uri"); if (null != uristr){ uristr = urldecoder.decode(uristr,"utf-8"); if (uristr.startswith("file://")){ uristr = uristr.substring(7); return new file(uristr); }else if (uristr.startswith("hbase://")){ try { return new file(new uri(uristr)); } catch (urisyntaxexception e) { log.error(e.getmessage(),e); } } } throw new runtimeexception("it's not a real uri"); } }
range支持
import java.io.file; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; /** * 文件处理工具 * @author jdkleo * */ public class fileutil { /** * 断点续传支持 * @param file * @param request * @param response * @return 跳过多少字节 */ public static long headersetting(file file,httpservletrequest request, httpservletresponse response) { long len = file.length();//文件长度 if ( null == request.getheader("range") ){ setresponse(new rangesettings(len),file.getname(),response); return 0; } string range = request.getheader("range").replaceall("bytes=", ""); rangesettings settings = getsettings(len,range); setresponse(settings,file.getname(),response); return settings.getstart(); } private static void setresponse(rangesettings settings,string filename, httpservletresponse response) { response.addheader("content-disposition", "attachment; filename=\"" + ioutil.toutf8string(filename) + "\""); response.setcontenttype( ioutil.setcontenttype(filename));// set the mime type. if (!settings.isrange()) { response.addheader("content-length", string.valueof(settings.gettotallength())); } else { long start = settings.getstart(); long end = settings.getend(); long contentlength = settings.getcontentlength(); response.setstatus(javax.servlet.http.httpservletresponse.sc_partial_content); response.addheader("content-length", string.valueof(contentlength)); string contentrange = new stringbuffer("bytes ").append(start).append("-").append(end).append("/").append(settings.gettotallength()).tostring(); response.setheader("content-range", contentrange); } } private static rangesettings getsettings(long len, string range) { long contentlength = 0; long start = 0; long end = 0; if (range.startswith("-"))// -500,最后500个 { contentlength = long.parselong(range.substring(1));//要下载的量 end = len-1; start = len - contentlength; } else if (range.endswith("-"))//从哪个开始 { start = long.parselong(range.replace("-", "")); end = len -1; contentlength = len - start; } else//从a到b { string[] se = range.split("-"); start = long.parselong(se[0]); end = long.parselong(se[1]); contentlength = end-start+1; } return new rangesettings(start,end,contentlength,len); } }
range封装
public class rangesettings{ private long start; private long end; private long contentlength; private long totallength; private boolean range; public rangesettings(){ super(); } public rangesettings(long start, long end, long contentlength,long totallength) { this.start = start; this.end = end; this.contentlength = contentlength; this.totallength = totallength; this.range = true; } public rangesettings(long totallength) { this.totallength = totallength; } public long getstart() { return start; } public void setstart(long start) { this.start = start; } public long getend() { return end; } public void setend(long end) { this.end = end; } public long getcontentlength() { return contentlength; } public void setcontentlength(long contentlength) { this.contentlength = contentlength; } public long gettotallength() { return totallength; } public void settotallength(long totallength) { this.totallength = totallength; } public boolean isrange() { return range; } }
io流相关处理工具类
import java.io.inputstream; public class ioutil { public static string setcontenttype(string returnfilename){ string contenttype = "application/octet-stream"; if (returnfilename.lastindexof(".") < 0) return contenttype; returnfilename = returnfilename.tolowercase(); returnfilename = returnfilename.substring(returnfilename.lastindexof(".")+1); if (returnfilename.equals("html") || returnfilename.equals("htm") || returnfilename.equals("shtml")){ contenttype = "text/html"; } else if (returnfilename.equals("css")){ contenttype = "text/css"; } else if (returnfilename.equals("xml")){ contenttype = "text/xml"; } else if (returnfilename.equals("gif")){ contenttype = "image/gif"; } else if (returnfilename.equals("jpeg") || returnfilename.equals("jpg")){ contenttype = "image/jpeg"; } else if (returnfilename.equals("js")){ contenttype = "application/x-javascript"; } else if (returnfilename.equals("atom")){ contenttype = "application/atom+xml"; } else if (returnfilename.equals("rss")){ contenttype = "application/rss+xml"; } else if (returnfilename.equals("mml")){ contenttype = "text/mathml"; } else if (returnfilename.equals("txt")){ contenttype = "text/plain"; } else if (returnfilename.equals("jad")){ contenttype = "text/vnd.sun.j2me.app-descriptor"; } else if (returnfilename.equals("wml")){ contenttype = "text/vnd.wap.wml"; } else if (returnfilename.equals("htc")){ contenttype = "text/x-component"; } else if (returnfilename.equals("png")){ contenttype = "image/png"; } else if (returnfilename.equals("tif") || returnfilename.equals("tiff")){ contenttype = "image/tiff"; } else if (returnfilename.equals("wbmp")){ contenttype = "image/vnd.wap.wbmp"; } else if (returnfilename.equals("ico")){ contenttype = "image/x-icon"; } else if (returnfilename.equals("jng")){ contenttype = "image/x-jng"; } else if (returnfilename.equals("bmp")){ contenttype = "image/x-ms-bmp"; } else if (returnfilename.equals("svg")){ contenttype = "image/svg+xml"; } else if (returnfilename.equals("jar") || returnfilename.equals("var") || returnfilename.equals("ear")){ contenttype = "application/java-archive"; } else if (returnfilename.equals("doc")){ contenttype = "application/msword"; } else if (returnfilename.equals("pdf")){ contenttype = "application/pdf"; } else if (returnfilename.equals("rtf")){ contenttype = "application/rtf"; } else if (returnfilename.equals("xls")){ contenttype = "application/vnd.ms-excel"; } else if (returnfilename.equals("ppt")){ contenttype = "application/vnd.ms-powerpoint"; } else if (returnfilename.equals("7z")){ contenttype = "application/x-7z-compressed"; } else if (returnfilename.equals("rar")){ contenttype = "application/x-rar-compressed"; } else if (returnfilename.equals("swf")){ contenttype = "application/x-shockwave-flash"; } else if (returnfilename.equals("rpm")){ contenttype = "application/x-redhat-package-manager"; } else if (returnfilename.equals("der") || returnfilename.equals("pem") || returnfilename.equals("crt")){ contenttype = "application/x-x509-ca-cert"; } else if (returnfilename.equals("xhtml")){ contenttype = "application/xhtml+xml"; } else if (returnfilename.equals("zip")){ contenttype = "application/zip"; } else if (returnfilename.equals("mid") || returnfilename.equals("midi") || returnfilename.equals("kar")){ contenttype = "audio/midi"; } else if (returnfilename.equals("mp3")){ contenttype = "audio/mpeg"; } else if (returnfilename.equals("ogg")){ contenttype = "audio/ogg"; } else if (returnfilename.equals("m4a")){ contenttype = "audio/x-m4a"; } else if (returnfilename.equals("ra")){ contenttype = "audio/x-realaudio"; } else if (returnfilename.equals("3gpp") || returnfilename.equals("3gp")){ contenttype = "video/3gpp"; } else if (returnfilename.equals("mp4") ){ contenttype = "video/mp4"; } else if (returnfilename.equals("mpeg") || returnfilename.equals("mpg") ){ contenttype = "video/mpeg"; } else if (returnfilename.equals("mov")){ contenttype = "video/quicktime"; } else if (returnfilename.equals("flv")){ contenttype = "video/x-flv"; } else if (returnfilename.equals("m4v")){ contenttype = "video/x-m4v"; } else if (returnfilename.equals("mng")){ contenttype = "video/x-mng"; } else if (returnfilename.equals("asx") || returnfilename.equals("asf")){ contenttype = "video/x-ms-asf"; } else if (returnfilename.equals("wmv")){ contenttype = "video/x-ms-wmv"; } else if (returnfilename.equals("avi")){ contenttype = "video/x-msvideo"; } return contenttype; } // utf8转码 public static string toutf8string(string s) { stringbuffer sb = new stringbuffer(); int len = s.tochararray().length; for (int i = 0; i < len; i++) { char c = s.charat(i); if (c >= 0 && c <= 255) { sb.append(c); } else { byte[] b; try { b = character.tostring(c).getbytes("utf-8"); } catch (exception ex) { system.out.println(ex); b = new byte[0]; } for (int j = 0; j < b.length; j++) { int k = b[j]; if (k < 0) k += 256; sb.append("%" + integer.tohexstring(k).touppercase()); } } } string s_utf8 = sb.tostring(); sb.delete(0, sb.length()); sb.setlength(0); sb = null; return s_utf8; } public static inputstream skipfully(inputstream in,long howmany)throws exception{ long remainning = howmany; long len = 0; while(remainning>0){ len = in.skip(len); remainning -= len; } return in; } }
注有些类比如ioutil方法来自于csdn的网友总结,另外此类还不支持多range配置如[a-b,c-d,-e]等。
希望本文所述对大家java程序设计有所帮助。
上一篇: VS初始化命令 ASP.NET常用技巧