一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java編程實現服務器端支持斷點續傳的方法(可支持快車、迅雷)

Java編程實現服務器端支持斷點續傳的方法(可支持快車、迅雷)

2020-01-21 15:14jdkleo JAVA教程

這篇文章主要介紹了Java編程實現服務器端支持斷點續傳的方法,涉及Java文件傳輸的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下

本文實例講述了Java編程實現服務器端支持斷點續傳的方法。分享給大家供大家參考,具體如下:

大家知道Tomcat之流對靜態資源可以實現斷點續傳支持,但是如果是一個被控制的流,如有權限控制,或下載地址僅是個代理的時候,這時候需要自己實現斷點續傳的支持,小弟不才,這里提供基本斷點續傳[a-,-b,a-b]的簡單實現,經驗證,可支持迅雷7和火狐的多次斷點續傳。現貼出代碼,大家共同分享:

Servlet

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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支持

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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封裝

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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流相關處理工具類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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程序設計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 99影视在线视频免费观看 | 午夜AV亚洲一码二中文字幕青青 | 天选之王漫画顾长歌免费阅读 | 青青草高清视频 | 色花堂中文字幕98堂网址 | 男人天堂资源网 | 青青青青青操 | 好大好硬抽搐好爽想要 | 草草视频在线免费观看 | 亚洲欧美在线免费观看 | 国产精品女同久久免费观看 | 日本免费三片在线观看 | 精品一区二区三区高清免费观看 | 亚洲v成人天堂影视 | 大象传媒2021秘密入口 | 免费一级特黄特色大片在线观看 | 扒开双腿猛进入爽爽视频ai | 视频免费观看在线播放高清 | 日韩欧美一区二区三区中文精品 | 护士videossexo另类 | 欧美丰满大乳大屁在线观看股 | 99青青青精品视频在线 | 毛片视频网站在线观看 | 91亚洲精品国产自在现线 | 欧美三级不卡在线观线看高清 | 免费观看毛片视频 | 91你懂的 | 亚洲aⅴ天堂 | 91亚洲视频在线观看 | 国产成人91高清精品免费 | 亚洲伦理视频 | bt伙计最新合集 | 调教麻麻成贱m | 午夜在线观看免费完整直播网页 | 欧美国产日本精品一区二区三区 | 亚洲啊v天堂 | 日本b站一卡二不卡三卡四卡 | 18性夜影院午夜寂寞影院免费 | 国产99re在线观看69热 | 91视频国产精品 | 深夜国产在线 |