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

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

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>

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美日韩亚洲综合在线一区二区 | 久久99热狠狠色一区二区 | 天天色一色 | 不卡一区二区三区 | 亚洲 欧美 中文 日韩欧美 | 91传媒制片厂果冻有限公司 | 无人区在线观看免费完整版免费 | 母性本能在线观看 | 日本在线色 | 久久精品男人影院 | 日本高清免费不卡在线播放 | 天天乐影院 | 久久中文字幕亚洲 | 欧美特级特黄a大片免费 | 极品主播的慰在线播放 | 三极黄色 | 免费观看视频网站 | 国产亚洲综合精品一区二区三区 | 99免费视频| 亚洲欧美成人中文在线网站 | 色视频久久 | 91久操| 小黄鸭YELLOWDUCK7596 | 冰雪奇缘1完整版免费观看 变形金刚第一部 | 四虎影视免费观看 | 日本三级免费网站 | 青草碰人人澡人人澡 | 调教全程肉动画片在线观看 | 2015台湾永久免费平台 | 插鸡网站| 久久se视频精品视频在线 | 国产精品日本一区二区三区在线看 | 国产亚洲精品精品国产亚洲综合 | 国产91青青成人a在线 | 午夜爽喷水无码成人18禁三级 | 97理伦| 亚洲精品久久麻豆蜜桃 | 无码AV精品一区二区三区 | 欧美亚洲视频在线观看 | 动漫美女日批 | 好逼天天有 |