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

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

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不卡在线| av在线免费观看播放 | 成人黄色网战 | 最近日本电影hd免费观看 | 精品在线视频播放 | 免费在线观看成年人视频 | 黄视频网址| 曰本三级日本三级日本三级 | 天天色综合2 | 国产在线精品一区二区夜色 | 欧美日韩免费在线观看视频 | 一级黄色片武则天 | 激情视频免费看 | 亚洲免费视 | 免费国产视频大全入口 | 精品成人一区二区三区 | 日韩精品一区二 | 亚洲最大中文字幕 | 成人免费久久 | 久久国产一二区 | 亚洲va久久久噜噜噜久牛牛影视 | 国产九九九九 | 国产91在线亚洲 | 偿还电影免费看 | 丁香桃色网 | 毛片大全在线观看 | 做羞羞视频 | 久久精品久久精品久久精品 | 黄色美女网站免费看 | 中文字幕在线观看www | 国产精品91在线 | 激情视频导航 | 国产精品久久久久久久久久妇女 | 史上最强炼体老祖动漫在线观看 | 97视频一二区| 蜜桃一本色道久久综合亚洲精品冫 | 亚洲一区久久久 | 91精品国产福利尤物免费 |