我刚听到断点续传,感觉好高端的样子,因为从来没听说过这个名词,但是看了别人的博客之后,发现,实现断点续传的功能并没有想象中的那么复杂。

在做断点续传之前,我们可以先来看下普通的文件下载功能是怎么实现的,普通的文件下载功能实现起来是很简单的,代码如下:

URL url = null;
HttpURLConnection httpURLConnection = null;
BufferedInputStream bufferedReader;
try {
url = new URL(downloadUrl);
httpURLConnection = (HttpURLConnection)url.openConnection();
httpURLConnection.setUseCaches(false); // 请求时不使用缓存
httpURLConnection.setConnectTimeout(5 * 1000); // 设置连接超时时间
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("Accept-Language", "zh-CN");
httpURLConnection.setRequestProperty("Charset", "UTF-8");
httpURLConnection.connect();
int bufferSize = 1024;
bufferedReader = new BufferedInputStream(httpURLConnection.getInputStream(),bufferSize); //为InputStream类增加缓冲区功能
int len = 0; //读取到的数据长度
byte[] buffer = new byte[bufferSize];
//写入中间文件
mOutputStream = new FileOutputStream(mTempFile,true);//true表示向打开的文件末尾追加数据
mByteOutput = new ByteArrayOutputStream();
//开始读取
while((len = bufferedReader.read(buffer)) != -1) {
mByteOutput.write(buffer,0,len);
}
mByteOutput.close();
bufferedReader.close();
}catch (MalformedURLException malformedURLException){
malformedURLException.printStackTrace();
}catch (IOException ioException){
ioException.printStackTrace();
}finally {
if(httpURLConnection!=null){
httpURLConnection.disconnect();
httpURLConnection = null;
}
}

使用以上这些代码就可以实现普通的文件下载功能。

如果用户在下载的过程中突然想暂停下载,那么,上面的那段代码就不能满足需求了,这个时候就有了断点续传的概念了。断点续传的概念简单来说就是在下载的过程中暂停,继续下载时接着上一次的进度继续下载,直到下载完成。

现在,我们来说下断点续传的原理,断点续传的原理其实也很简单,从上面那段代码我们可以知道,文件的下载过程其实就是字节的读取和写入的过程,而断点续传,就是在字节读取过程中停止之后,又能接着上次的进度继续读取字节。那我们要实现这个功能,就需要在每次读取字节时记录读取的字节,然后在继续下载的时候继续上次的字节读取。

那么具体怎么来实现这个功能呢?其实很简单,只需要使用这几行代码就能实现:

首先在字节读取的地方加上字节长度的记录:

while((len = bufferedReader.read(buffer)) != -1) {
mByteOutput.write(buffer,0,len);
mLoadedByteLength += mByteOutput.size();
}

然后在发起下载请求的时候加上这行代码:

if(mLoadedByteLength > 0 && mLoadedByteLength < mTotalByteLength){
httpURLConnection.setRequestProperty("Range", "bytes=" + mLoadedByteLength + "-");
}

这样就能实现断点续传的功能,看完这些是不是感觉很简单啊。

效果图如下:

download.gif

最后添上自己做的一个断点续传的小demo的github地址,这个demo或许存在着bug,不过这不重要,这个小demo主要目的就是为大家实现断点续传功能做参考。

ttps://github.com/fm183/DownloadFilePorject.git