java之断点续传简单实现

来源:互联网 发布:下载软件有哪些 编辑:程序博客网 时间:2024/05/28 09:32

断点续传主要是使用http协议中range的属性来取得资源的部分内容,由于一般服务是不对外直接提供url访问的,一般都是通过id,在servlet中输出byte[]来实现,所以要想实现断点续传一般要自己实现服务端和客户端,客户端保持文件的下载或上传状态,(保存在本地或者数据库中)。再进行中断时保持中断状态,在进行续传时,首先读出文件的状态,然后设置range属性信息发送续传请求。服务器收到续传请求,读取range属性值,从文件中读取数据,发送到客户端。上述是基本的原理,上传下载原理相同。

       下面模拟两次从服务器中现在文件。

       客户端:分多次取得部分文件内容,利用RandomAccessFile文件中读取数据,写到输出流中。

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package org.nercita.zmx.servlet;  
  2.   
  3. import java.io.FileNotFoundException;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.RandomAccessFile;  
  7. import java.net.HttpURLConnection;  
  8. import java.net.MalformedURLException;  
  9. import java.net.URL;  
  10.   
  11. public class LoadClient {  
  12.       
  13.     public static void load(int start, int end) throws MalformedURLException, FileNotFoundException{  
  14.           
  15.         String endpoint = "http://localhost:8080/RestDemo/servlet/LoadServlet?id=5";  
  16.               
  17.         URL url = new URL(endpoint);  
  18.         try {  
  19.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  20.             conn.setRequestProperty("Content-Type","text/plain; charset=UTF-8");   
  21.             conn.setRequestProperty("RANGE","bytes="+start+"-"+end); //header中增加range属性           
  22.             conn.connect();  
  23.             System.out.println(conn.getResponseCode());  
  24.             System.out.println(conn.getContentLength());  
  25.             System.out.println(conn.getContentType());  
  26.             InputStream ins = (InputStream)conn.getContent();     
  27.             String fileName=conn.getHeaderField("Content-Disposition");  
  28.             fileName = new String(fileName.getBytes("ISO8859-1"), "UTF-8");  
  29.             fileName=fileName.substring(fileName.lastIndexOf("\\")+1);  
  30.             System.out.println(fileName);  
  31.             RandomAccessFile raFile = new RandomAccessFile("E:\\"+fileName, "rw");  
  32.             raFile.seek(start);           
  33.             byte[] buffer = new byte[4096];  
  34.             int len = -1;  
  35.             while((len = ins.read(buffer))!=-1){  
  36.                 raFile.write(buffer,0,len);  
  37.             }  
  38.             raFile.close();  
  39.             conn.disconnect();  
  40.         } catch (IOException e) {  
  41.             e.printStackTrace();  
  42.         }  
  43.     }  
  44.   
  45.       
  46.     public static void main(String[] args) throws IOException {  
  47.           
  48.         load(0,1000);  
  49.         load(1001,0);  
  50.   
  51.       
  52.     }  
  53.   
  54. }  


 


服务端:获取分析range属性,从收入流读取内容字节流,利用RandomAccessFile输出到文件中。其中还解决了中文文件名乱码的问题,由于http协议中规定,当在网络中传输时,setHeader方法中的字符只能按ISO8859-1传输,所以这时候就要把Unicode字符转换成了ISO8859-1的编码传到客户端,客户端进行解码。否则会出现乱码。

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package org.nercita.zmx.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.RandomAccessFile;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.ServletOutputStream;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11.   
  12. public class LoadServlet extends HttpServlet {  
  13.   
  14.     private static final long serialVersionUID = 237208504975097723L;  
  15.   
  16.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  17.             throws ServletException, IOException {  
  18.         int id = Integer.parseInt(request.getParameter("id"));  
  19.         System.out.println(request.getContextPath());  
  20.         String path = request.getServletContext().getRealPath("/load");  
  21.         String filename = "" ;  
  22.         if (id == 1)  
  23.             filename = path+"JDK_API_1_5_zh_CN.CHM";  
  24.         else if (id == 2)  
  25.             filename = path+"JDK_API_1_6_zh_CN.CHM";  
  26.         else if (id == 3)  
  27.             filename = path+"tomcat.gif";  
  28.         else  
  29.             filename = path+"\\断点续传text.txt";  
  30.   
  31.         RandomAccessFile raFile = new RandomAccessFile(filename, "r");  
  32.           
  33.         String range = request.getHeader("RANGE");  
  34.         int start=0end=0;  
  35.         if(null!=range && range.startsWith("bytes=")){  
  36.             String[] values =range.split("=")[1].split("-");  
  37.             start = Integer.parseInt(values[0]);  
  38.             end = Integer.parseInt(values[1]);  
  39.         }  
  40.         int requestSize=0;  
  41.         if(end!=0 && end > start){  
  42.             requestSize = end - start + 1;  
  43.             response.addHeader("content-length", ""+(requestSize));  
  44.         } else {  
  45.             requestSize = Integer.MAX_VALUE;  
  46.         }  
  47.           
  48.         byte[] buffer = new byte[4096];           
  49.         response.setContentType("application/x-download");        
  50.         filename = new String(filename.getBytes("UTF-8"), "ISO8859-1");  
  51.         response.addHeader("Content-Disposition", "attachment;filename="+filename);  
  52.         ServletOutputStream os = response.getOutputStream();  
  53.         int needSize = requestSize;  
  54.         raFile.seek(start);  
  55.         while(needSize > 0){  
  56.             int len = raFile.read(buffer);  
  57.             if(needSize < buffer.length){  
  58.                 os.write(buffer,0,needSize);  
  59.             } else {  
  60.                 os.write(buffer,0,len);  
  61.                 if(len < buffer.length){  
  62.                     break;  
  63.                 }  
  64.             }  
  65.             needSize -buffer.length;  
  66.         }  
  67.               
  68.         raFile.close();  
  69.         os.close();  
  70.   
  71.   
  72.     }  
  73.   
  74.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  75.             throws ServletException, IOException {  
  76.       
  77.          this.doGet(request, response);  
  78.   
  79.     }  
  80.   
  81. }  


             上述代码,已通过本人测试,有兴趣的可以一试!

0 1
原创粉丝点击