java list断点续传_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部分
showDownloadFileNameList
3. jsp部分
文件下載總結
以上是生活随笔為你收集整理的java list断点续传_java实现文件断点续传下载功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java数组元素相加_数组元素相加
- 下一篇: java main 参数传递参数_Jav