端点续传其实是一个很简单的原理。需要服务器端支持才行。客户端实现很简单,就算基本的读写文件。
HTTP头示例:
# The first 500 bytes:
Content-Range: bytes 0-499/1234
# The second 500 bytes:
Content-Range: bytes 500-999/1234
# All except for the first 500 bytes:
Content-Range: bytes 500-1233/1234
# The last 500 bytes:
Content-Range: bytes 734-1233/1234
下载的时候查看HTTP头,如果HTTP头里面包含了Range等就提取出来,计算出下一块读取的位置和长度,然后用Content-Range头返回。
客户端直接读取和保存文件
读取的时候先跳过已经下载的长度。
if (!downloadPath.exists())
downloadPath.mkdirs();
if (outputFileCache.exists())
{
downloadedSize = outputFileCache.length();
connection.setAllowUserInteraction(true);
connection.setRequestProperty("Range", "bytes=" + downloadedSize + "-");
connection.setConnectTimeout(14000);
connection.connect();
input = new BufferedInputStream(connection.getInputStream());
output = new FileOutputStream(outputFileCache, true);
input.skip(downloadedSize); //Skip downloaded size
}
else
{
connection.setConnectTimeout(14000);
connection.connect();
input = new BufferedInputStream(url.openStream());
output = new FileOutputStream(outputFileCache);
}
fileLength = connection.getContentLength();
byte data[] = new byte[1024];
int count = 0;
int __progress = 0;
long total = downloadedSize;
while ((count = input.read(data)) != -1 && !this.isInterrupted())
{
total += count;
output.write(data, 0, count);
__progress = (int) (total * 100 / fileLength);
}
output.flush();
output.close();
input.close();
服务器端使用Servlet支持端点续传下载:
/*
* net/balusc/webapp/FileServlet.java
*
* Copyright (C) 2009 BalusC
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library.
* If not, see .
*/
package net.balusc.webapp;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A file servlet supporting resume of downloads and client-side caching and GZIP of text content.
* This servlet can also be used for images, client-side caching would become more efficient.
* This servlet can also be used for text files, GZIP would decrease network bandwidth.
*
* @author BalusC
* @link http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and.html
*/
public class FileServlet extends HttpServlet {
// Constants ----------------------------------------------------------------------------------
private static final int DEFAULT_BUFFER_SIZE = 10240; // ..bytes = 10KB.
private static final long DEFAULT_EXPIRE_TIME = 604800000L; // ..ms = 1 week.
private static final String MULTIPART_BOUNDARY = "MULTIPART_BYTERANGES";
// Properties ---------------------------------------------------------------------------------
private String basePath;
// Actions ------------------------------------------------------------------------------------
/**
* Initialize the servlet.
* @see HttpServlet#init().
*/
public void init() throws ServletException