断点续传
所谓断点续传,就是将下载进度保存到一个文件中,下载开始下载的时候,先读取这个文件,根据文件描述的进度继续下载,下载完毕后,删除进度临时文件。
昨天做了Java的多线程下载,如果要给多线程下载加上断点续传,就需要在每个线程写入数据时,在配置文件中写入该线程一共写入了多少目标数据的记录,在下次开始下载的时候,判断临时进度文件是否存在,存在的话,读取这个配置文件中描述的各个线程的下载进度,重新给各个线程分配目标数据进行下载。
File pFile = new File(tid + ".txt");
if (pFile.exists()) {//进度文件存在
InputStream p_is = new FileInputStream(pFile);
BufferedReader reader = new BufferedReader(new InputStreamReader(p_is));
progress = Integer.parseInt(reader.readLine());
startIndex = progress + 1;
p_is.close();
}
而在写入的时候,每写入一次的时候,同时更新已下载总字节数的记录
int total = progress;//total表示当前总共已经下载了多少字节,不表示这次开启线程下载了多少。所以应该和进度文件的保持一致
int index = 0;
while ((len = is.read(buf)) != -1) {
raf.write(buf, 0, len);
total = total + len;
//写入该线程的进度
RandomAccessFile raf_p = new RandomAccessFile(pFile, "rwd");//把这行代码放在循环里面,可以保证是覆盖写入而不是追加
raf_p.write((total + "").getBytes());//这里必须要将total转成字符串,才能调用getBytes,写入。
raf_p.close();
index++;
}
而在每个线程下载完后,标注该线程已经下载完成了,具体就是删除描述该线程下载记录的文件,当所有线程都下载完毕后(已完成下载的线程总数等于总线程数),删除所有临时进度文件,下载完毕,但是由于是多线程并发操作,可能在删除文件的时候出现线程不安全的,应该加同步保证线程安全。
Main.finishedThread++;
System.out.println("第" + tid + "个线程 :" + "finishedThread = " + finishedThread);
<pre name="code" class="java">if (Main.finishedThread == Main.threadCount) {//所有线程都下载完毕了,删除临时进度文件
synchronized (Main.path) {//防止在这个线程正在删除的同时,另外一个线程也在删,保证线程安全
System.out.println("-----------删除了");
for (int i = 0; i < Main.threadCount; i++) {
File tempFile = new File(i + ".txt");
tempFile.delete();
}
Main.finishedThread = -1;
}
}
同时在测验中发现,在下载的while循环中加上另一个文件的写入操作明显使下载速度变慢了。。。