原理:主要是使用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