java完成文件斷點續傳下載功效。本站提示廣大學習愛好者:(java完成文件斷點續傳下載功效)文章只能為提供參考,不一定能成為您想要的結果。以下是java完成文件斷點續傳下載功效正文
本文實例為年夜家分享了java斷點續傳下載的代碼,供年夜家參考,詳細內容以下
1. Java代碼
//完成文件下載功效
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>