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

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

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

服務器之家 - 編程語言 - JAVA教程 - java實現文件斷點續傳下載功能

java實現文件斷點續傳下載功能

2020-05-05 14:13鐘志誠 JAVA教程

這篇文章主要為大家詳細介紹了java實現文件斷點續傳下載功能的具體代碼,感興趣的小伙伴們可以參考一下

本文實例為大家分享了java斷點續傳下載的代碼,供大家參考,具體內容如下

1. Java代碼    

?
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
//實現文件下載功能
  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部分    

復制代碼 代碼如下:
<action name="downloadFile" class="downloadFileAction" method="downloadFile">
   <result name="failed" type="redirectAction">showDownloadFileNameList</result>
</action>

 

 

3. jsp部分    

復制代碼 代碼如下:
<td><a href="downloadFile?filename=${fileMap.key }&&filepath=${fileMap.value }">文件下載</a></td>

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人久久精品一区二区三区 | 国产精品女主播自在线拍 | 91手机看片国产永久免费 | 亚洲国产精品成人午夜在线观看 | 四虎影音 | a级成人毛片免费图片 | 成年男女免费大片在线观看 | 色综合天天综合网国产人 | 啊啊啊好大好爽视频 | 免费在线视频网站 | 97菊爱网| 国产成人精品高清在线观看99 | 欧美日本一道高清免费3区 欧美人做人爱a全程免费 | 嫩模被黑人粗大挺进 | 99热久久这里只精品国产www | 甜宠巨肉h文1v1校园 | 成人国产精品一级毛片视频 | 欧美xxx000喷水 | 国产51社区精品视频资源 | 香蕉草莓视频 | 日本大片网 | 国产亚洲一欧美一区二区三区 | 日韩一区二三区无 | 午夜在线播放免费人成无 | 青青视频国产依人在线 | 9总探花新品牛仔背带裤 | 亚洲AV 无码AV 中文字幕 | 啪啪艹| 亚洲网视频 | 精品久久香蕉国产线看观看亚洲 | 亚洲精品123区在线观看 | 色综合天天综合网国产人 | www.四虎.com| 久青草国产在线观看视频 | 五月婷婷俺也去开心 | 大学生宿舍飞机china free | 欧美高清在线 | 色中色官网 | 蜜柚精彩在线观看 | 啊啊啊好大好爽视频 | 欧美专区在线观看 |