java 斷點續傳

原理:主要是使用HTTP協議中range屬性來取得資源的部分內容,由於一般服務是不對外直接聽過url訪問的,一般都是通過ID,在servlet中輸出byte[]來實現,所以要想實現蹲點續傳一般要自己實現服務端和客戶端,客戶端保持文件的下載和上傳文件狀態,可以保存在本地或者數據庫中。宰金鑫中斷時保持中斷狀態,在進行續傳時,首先讀出文件的狀態,然後設置range屬性信息發送續傳請求。服務器收到續傳請求,讀取range屬性值,從文件中讀取數據,發送到客戶端。上傳和下載的原理是一樣的。

客戶端:

/**
* 實現斷點續傳的客戶端
* @author uj
*
*/
public class LoadClient {
     public static void load(int start, int end) throws Exception {
          String endpoint = "http://localhost:8080/RestDemo/LoadServlet?id=5";;;
          URL url = new URL(endpoint);

          HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          connection.setRequestProperty("Content-Type", "text/plain;charset=UTF-8");
          connection.setRequestProperty("RANGE","bytes="+start+"-"+end);//在header中增加range屬性
          connection.connect();

          System.out.println(connection.getResponseCode());
          System.out.println(connection.getContentLength());
          System.out.println(connection.getContentType());

          InputStream is = (InputStream) connection.getContent();
          String filename = connection.getHeaderField("Content-Disposition");
          filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");
          filename = filename.substring(filename.lastIndexOf("\\")+1);
          System.out.println(filename);

          RandomAccessFile raf = new RandomAccessFile("D:\\"+filename,"rw");
          raf.seek(start);

          byte[] buf = new byte[1024];
          int len = 0;
          while((len = is.read(buf))!=-1) {
              raf.write(buf,0,len);
          }
          raf.close();       
     }

     public static void main(String[] args) throws Exception {
//        load(0,1000); //下載前1000個字節的數據
          load(1001, 0); //下載剩餘字節的數據
     }
}

服務端:需要使用JavaEE開發工具和Tomcat服務器環境

/**
* 斷點下載的服務端
*/
@WebServlet("/LoadServlet")
public class LoadServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;


     /**
      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
      */
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          int id = Integer.parseInt(request.getParameter("id"));
          System.out.println(request.getContextPath());
          String path = request.getServletContext().getRealPath("load");
          String filename = "";
          if(id == 1){
              filename = path+"1.jpg";              
          }else if(id == 2){
              filename = path+"2.jpg";
          }else  if(id == 3){
              filename = path+"3.jpg";
          }else{
               filename = path+"斷點續傳.txt";
          }

          RandomAccessFile raf = new RandomAccessFile(filename,"r");
          String range = request.getHeader("RANGE");
          int start = 0;
          int end = 0;
          if(null!=range && range.startsWith("bytes=")){
              String[] values = range.split("=")[1].split("-");
              start = Integer.parseInt(values[0]);
              end = Integer.parseInt(values[1]);
          }
          int requestSize = 0;
          if(end!=0 && end>start){
              requestSize = end-start+1;
              response.addHeader("content-length", ""+(requestSize));
          }else{
              requestSize=Integer.MAX_VALUE;
          }

          byte[] buf = new byte[1024];
          response.setContentType("application/x-download");
          filename = new String(filename.getBytes("UTF-8"),"ISO8859-1");
          response.addHeader("Content-Disposition", "attachment;filename="+filename);
          ServletOutputStream os = response.getOutputStream();
          int needSize = requestSize;
          raf.seek(start);
          while(needSize > 0){
              int len = raf.read(buf);
              if(needSize<buf.length){
                   os.write(buf,0,needSize);
              }else{
                   os.write(buf,0,len);
                   if(len<buf.length){
                        break;
                   }
              }
              needSize -=buf.length;
          }

          raf.close();
          os.close();        

     }
     /**
      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
      */
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          this.doGet(request, response);
     }
}

這裏寫圖片描述
其中文件:load斷點續傳.txt 文件要放在WebContent文件夾下

項目下載鏈接:http://download.csdn.net/download/studyofandroid/10249181

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