关键点
1.文件下载使用原生的HttpURLConnection
来下载,获取输入流保存到本地文件就可以了;
2.限速可以在读取输入流的时候设置时间间隔,每一秒只读取固定的大小即可实现限速效果;
3.断点续传需要在取消下载的时候记录这个文件路径,再次下载的时候如果记录中有这个文件则继续从文件末尾开始读写,请求文件的时候需要在HTTP请求里面设置参数,告诉服务器跳过已下载部分(即跳过本地文件大小的字节)
具体实现
获取输入流
首先新建HttpDownloadImpl
类,实现接口,实现下载方法,打开URL获取文件输入流
1 2 3 4 5 6 7 8
| String urlStr = fileUrl; HttpURLConnection conn = null; InputStream inputStream = null; url = new URL(urlStr); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(CONNECT_TIME_OUT); inputStream = conn.getInputStream();
|
写入到本地文件
写入到本地文件很简单,根据本地文件创建输出流从输入流读取数据循环写入即可
1 2 3 4 5 6 7
| OutputStream outputStream = new FileOutputStream(new File(savePath)); byte[] bytes = new byte[1024]; int read = inputStream.read(bytes); while (read != -1) { outputStream.write(bytes,0,read); read = inputStream.read(bytes); }
|
下载限速
做下载限速就需要控制while循环里面的输入流的读取速度,方法很简单,如果在单位时间内,下载速度已经达到了限速的大小,则等待剩下的时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| downLoadSize = downLoadSize + increment;
if (downLoadSize - speedLastDownloadSize >= transferSpeed) { long interval = System.currentTimeMillis() - speedLimitLasttime; if (interval < speedLimitTime) { try { Thread.sleep(speedLimitTime - interval); } catch (InterruptedException e) { e.printStackTrace(); } } speedLastDownloadSize = downLoadSize; speedLimitLasttime = System.currentTimeMillis(); }
|
获取下载进度
获取下载进度比较简单,获取到文件的总大小和当前累计的下载大小即可
1 2
| int contentLength = conn.getContentLength();
|
暂停、继续下载
暂停下载也比较简单,只需要在循环读取数据里面添加一个boolean
类型的变量即可控制暂停或者继续下载了
断点续传
断点续传其实很简单,关键在于两点,一是写入文件的时候需要跳到文件的末尾继续进行写入,二是HTTP获取输入流的时候需要通知服务器只传文件未下载的部分;至于下载了多少不需要保存,只需要从已下载的文件读取即可,所以需要记录一下哪些文件是未下载完需要继续下载的;
1 2 3 4 5 6 7 8 9
| downloadedLength = newFile.length(); conn.setRequestProperty("RANGE", "bytes=" + downloadedLength);
RandomAccessFile outputStream = null; outputStream = new RandomAccessFile(newFile, "rw"); outputStream.seek(downloadedLength);
|