Javaweb 實現斷點續傳

Javaweb 實現斷點續傳

1.方法

代碼

package cn.test.servlet;

 

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.RandomAccessFile;

 

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.HttpClient;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.DefaultHttpClient;

 

public classdown extends HttpServlet {

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException,IOException {

        ServletContextservletContext=getServletContext();//獲得servletContext對象

        request.setCharacterEncoding("utf-8");//設置編碼格式

        Stringurl = "http://dlsw.baidu.com/sw-search-sp/soft/3a/12350/QQ5.3.10716.0.1397783519.exe";//獲得下載地址

        StringdownFile = "C:\\Users\\Administrator\\Desktop\\QQ.exe";//獲得保存地址

        LongnetFileLenght = getNetFileSize(url);//獲得網絡數據字符流長度

        LonglocalFileLenght = getLocalFileSize(downFile);//獲得已下載本地數據字符流長度

        request.setAttribute("process",netFileLenght);

        servletContext.getRequestDispatcher("/MyJsp.jsp").forward(request,response);

 

        if (localFileLenght >=netFileLenght) {

            System.out.println("已下載完成");

            return;

        }

        System.out.println("netFileLenght : "+ netFileLenght+ " localFileLenght : " + localFileLenght);

        final HttpClient httpClient =newDefaultHttpClient();

        httpClient.getParams().setIntParameter("http.socket.timeout",5000);

 

        final HttpGet httpGet = new HttpGet(url);

        httpGet.addHeader("Range","bytes="+ localFileLenght + "-");

        final HttpResponse response1= httpClient.execute(httpGet);

        final int code =response1.getStatusLine().getStatusCode();

        final HttpEntity entity =response1.getEntity();

        System.out.println(code);

 

        if (entity != null && code <400) {

 

            Filefile = newFile(downFile);

            RandomAccessFilerandomAccessFile = new RandomAccessFile(file,"rw");

            randomAccessFile.seek(localFileLenght);

 

            InputStreaminputStream = entity.getContent();

            int b = 0;

            final byte buffer[] = new byte[1024];

            while ((b = inputStream.read(buffer)) != -1) {

                randomAccessFile.write(buffer, 0, b);

            }

 

            randomAccessFile.close();

            inputStream.close();

            httpClient.getConnectionManager().shutdown();

            System.out.println("下載完成");

           

        }

 

    }

 

    public static LonggetLocalFileSize(String fileName) {//獲取本地保存地址的字符流長度

        Filefile = newFile(fileName);

        return file.length();

    }

 

    public static LonggetNetFileSize(String url) {//獲取網絡下載地址的字符流長度

        Longcount = -1L;

        final HttpClient httpClient =newDefaultHttpClient();

        httpClient.getParams().setIntParameter("http.socket.timeout",5000);

 

        final HttpGet httpGet = new HttpGet(url);

        HttpResponseresponse = null;

        try {

            response= httpClient.execute(httpGet);

            final int code=response.getStatusLine().getStatusCode();

            final HttpEntity entity=response.getEntity();

            if (entity != null && code == 200){

                count= entity.getContentLength();

               }

           }

        catch(ClientProtocolException e) {

            e.printStackTrace();

        }catch(IOException e) {

            e.printStackTrace();

        }finally{

            httpClient.getConnectionManager().shutdown();

        }

        return count;

    }

 

    public voiddoPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException,IOException {

        doGet(request, response);

    }

 

}

getNetFileSize這個方法是在網上找的

大概流程是index.jsp通過超文本連接調用down.java這個servlet,servlet獲取下載地址以及保持位置,通過getLocalFileSize和getNetFileSize兩個方法獲得本地保存位置的文件的字節數和遠程資源文件的字節數,進行判斷,如果小於後者,則在前者字節數基礎上繼續下載,如果相等則下載完畢。轉發給MyJsp.jsp.

測試圖片:

第一行數據爲初次下載時

遠程資源爲58325176

檢測本地文件資源爲0

即前尚未下載。

第二行數據爲關閉瀏覽器後,重新打開下載

檢測到遠程資源爲58325176

檢測本地文件資源爲8779765

小於第一個數

則繼續下載

第三行和第二行一樣

 

 

2.方法

瀏覽器第一次下載時會先用一個變量

記錄下載數據的字節數通過cookie保存在客戶電腦中,生命週期較長

下次打開時,讀取這個變量,然後在變量加1的位置繼續下載

其實兩者差不多

 

關於下載進度條

1.html5+javascript

代碼

<!DOCTYPE html>

<html>

<head>

<title>down</title>

<script type="text/javascript">

var currProgress = 0;

var done = false;

var total = 100;

 

function startProgress() {

var prBar =document.getElementById("prog");

var startButt =document.getElementById("startBtn");

var val =document.getElementById("numValue");

startButt.disabled=true;

prBar.value = currProgress;

val.innerHTML =Math.round((currProgress/total)*100)+"%";

 

currProgress++;

if(currProgress>100) done=true;

if(!done)

   setTimeout("startProgress()", 100);

else    

{

   document.getElementById("startBtn").disabled = false;

   done = false;

   currProgress = 0;

}

}

</script>

</head>

<body>

 

 

 

<p>Task progress:</p>

<progress id="prog"value="0" max="100"></progress> 

<input id="startBtn"type="button" value="start" οnclick="startProgress()"/>

<divid="numValue">0%</div>

 

</body>

</html>

但是標籤progress在我的IE瀏覽器上無法使用

只會顯示下載百分比

現在只有火狐 谷歌 opera 上支持

2.javacript

<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<htmlxmlns="http://www.w3.org/1999/xhtml" >

<head>

<title>進度條</title>

<style type="text/css">

body{

text-align:center;

}

.graph{

width:450px;

border:1px solid #F8B3D0;

height:25px;

}

#bar{

display:block;

background:#FFE7F4;

float:left;

height:100%;

text-align:center;

}

#barNum{

position:absolute;

}

</style>

<scripttype="text/javascript">

function $(obj){

return document.getElementById(obj);

}

function go(){

$("bar").style.width =parseInt($("bar").style.width) + 1 + "%";

$("bar").innerHTML =$("bar").style.width;

if($("bar").style.width =="100%"){

window.clearInterval(bar);

}

 

}

var bar =window.setInterval("go()",50);

window.onload = function(){

bar;

}

</script>

</head>

<body>

<div class="graph">

<strong id="bar"style="width:1%;"></strong>

</div>

</body>

</html>

這個代碼沒看懂

 

下載進程問題

servlet將正下載數據字節數以及總數據數通過

resquest域傳給前臺

並不斷刷新進度顯示頁面,

需要多線程技術

因爲servlet是處理請求與響應的

如果下載時間很長,網頁不可能一直在等待處理結果

所以需要另外一個線程處理下載,並不斷返回已下載數據的字節數

可以通過Ajax讓進度顯示頁面不斷獲取此數據,並顯示

但是servlet中不能使用多線程(servlet本身就是多線程,這樣會使線程安全性很差)

需要使用javabean來創建線程(不知道對不對)

然後在servlet中調用javabean對象實現多線程


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章