断点续传,就是从文件已经下载的地方继续下载。这在下载比较大的文件时是一个非常有用的功能,实现断点下载的主要技术点有两个:一是多线程下载数据后,实时记录各个线程下载的数据量,二是从网络上分段下载数据。
下面我就简单的讲讲文件断点下载的简单思路:
首先,需要先使用HttpURLConnection,连接链接,获取文件的大小。
1 2 3 4 5
| HttpURLConnection conn= (HttpURLConnection) url.openConnection(); conn.connect(); if(conn.getResponseCode()==200){ int size=conn.getContentLength(); }
|
在获取文件的大小之后,需要以下几件事:
在没有下载过文件的情况下,创建与实际文件等大小的文件。在这个过程的时间会根据创建文件的大小而变化,你可以先创建多个文件,写入数据完成后将所有数据再写到同一个文件中,这里就不在做此操作。
1 2 3
| RandomAccessFile raf = new RandomAccessFile(file, "rw");//file是需要保存的文件 raf.setLength(size); raf.close();
|
获取各个线程已经下载的数据量(第一次时数据为0),获取不同线程需要下载的数据量(最后一个需要将剩余的数据全部下载),创建线程并且设置相应的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| for(int i=0;i<threadCount;i++){ int end=(i+1)*mFileSize; if(i==threadCount-1){ end=size; } int ds= DbUtil.getInteger(filePath+"thread"+i); FileDownloadThread fileDownloadThread =new FileDownloadThread.Builder(i) .filePath(filePath) .start(mFileSize*i) .httpUrl(httpUrl) .end(end) .downloadSize(ds) .downListener(downloadManager) .build();
downloadManagerList.add(fileDownloadThread); fileDownloadThread.startDownload();
|
在每个下载线程中,我们需要从不同从不同的位置下载数据(未下完时)。
1 2 3 4 5 6
| URL url = new URL(httpUrl); HttpURLConnection conn= (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Range","bytes="+(start+downloadSize)+"-"+end); conn.setRequestProperty("Connection","Keep-Alive");//使用长连接 conn.connect();
|
然后将数据写到文件的不同位置,同时需要将已经下载的数据量写入,以便下次打开时继续从原文件下载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| //得到输入流 InputStream inputStream = conn.getInputStream(); //获取自己数组 byte[] getData = new byte[1024];
File saveDir = new File(filePath); RandomAccessFile raf = new RandomAccessFile(saveDir, "rwd"); raf.seek(downloadSize+start); int offset=0; while((offset=inputStream.read(getData,0,1024))!=-1){ raf.write(getData,0,offset); downloadSize+=offset; DbUtil.saveInteger(filePath+"thread"+id,downloadSize); } if (raf != null) { raf.close(); } if (inputStream != null) { inputStream.close(); }
|
以上这些就是java断点下载最核心的代码,在具体实现中还有很多的细节和功能的优化。