激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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在线精品视频免费观看20 | 欧洲精品久久 | 精品视频一区二区三区四区 | 91网视频在线观看 | 99久久精品免费视频 | 欧美一级特黄aaaaaaa什 | 欧美a视频| 美女很黄很黄免费的 | 亚洲一区二区三区视频 | 12av毛片 | 欧美成人一区二区三区 | 做爰xxxⅹ性护士hd在线 | 久久一区三区 | 中文字幕免费一区 | 羞羞草视频 | 亚洲人成网站在e线播放 | 精品一区二区三区免费毛片 | 成熟女人特级毛片www免费 | 激情91| 国产人成免费爽爽爽视频 | 久久蜜桃精品一区二区三区综合网 | 免费黄色一级网站 | 日本aaa一级片 | 噜噜噜躁狠狠躁狠狠精品视频 | 国产免费视频一区二区裸体 | 欧美日韩在线视频一区 | 国产无遮挡一区二区三区毛片日本 | 成人免费一区二区三区在线观看 | 在线视频 亚洲 | 色婷婷久久一区二区 | 一区二区三区日韩精品 | 91久久久久久久久久久久久久 | 成年人在线视频 | 一级黄片毛片免费看 | 国产在线观看91精品 | 美女一级毛片 | 国产99精品视频 | 国产成年人在线观看 | 成人啪啪色婷婷久 | 久久草在线看 |