Java实现多线程断点下载
程序员文章站
2022-10-19 20:21:51
java多线程断点下载原理如图:
代码如下:
import java.io.bufferedreader;
import java.io.file;...
java多线程断点下载原理如图:
代码如下:
import java.io.bufferedreader; import java.io.file; import java.io.fileinputstream; import java.io.inputstream; import java.io.inputstreamreader; import java.io.randomaccessfile; import java.net.httpurlconnection; import java.net.url; public class mutilethreaddownload { /** * 线程的数量 */ private static int threadcount = 3; /** * 每个下载区块的大小 */ private static long blocksize; /** * 正在运行的线程的数量 */ private static int runningthreadcount; /** * @param args * @throws exception */ public static void main(string[] args) throws exception { // 服务器文件的路径 string path = "http://192.168.1.100:8080/ff.exe"; url url = new url(path); httpurlconnection conn = (httpurlconnection) url.openconnection(); conn.setrequestmethod("get"); conn.setconnecttimeout(5000); int code = conn.getresponsecode(); if (code == 200) { long size = conn.getcontentlength();// 得到服务端返回的文件的大小 system.out.println("服务器文件的大小:" + size); blocksize = size / threadcount; // 1.首先在本地创建一个大小跟服务器一模一样的空白文件。 file file = new file("temp.exe"); randomaccessfile raf = new randomaccessfile(file, "rw"); raf.setlength(size); // 2.开启若干个子线程分别去下载对应的资源。 runningthreadcount = threadcount; for (int i = 1; i <= threadcount; i++) { long startindex = (i - 1) * blocksize; long endindex = i * blocksize - 1; if (i == threadcount) { // 最后一个线程 endindex = size - 1; } system.out.println("开启线程:" + i + "下载的位置:" + startindex + "~" + endindex); new downloadthread(path, i, startindex, endindex).start(); } } conn.disconnect(); } private static class downloadthread extends thread { private int threadid; private long startindex; private long endindex; private string path; public downloadthread(string path, int threadid, long startindex, long endindex) { this.path = path; this.threadid = threadid; this.startindex = startindex; this.endindex = endindex; } @override public void run() { try { // 当前线程下载的总大小 int total = 0; file positionfile = new file(threadid + ".txt"); url url = new url(path); httpurlconnection conn = (httpurlconnection) url .openconnection(); conn.setrequestmethod("get"); // 接着从上一次的位置继续下载数据 if (positionfile.exists() && positionfile.length() > 0) {// 判断是否有记录 fileinputstream fis = new fileinputstream(positionfile); bufferedreader br = new bufferedreader( new inputstreamreader(fis)); // 获取当前线程上次下载的总大小是多少 string lasttotalstr = br.readline(); int lasttotal = integer.valueof(lasttotalstr); system.out.println("上次线程" + threadid + "下载的总大小:" + lasttotal); startindex += lasttotal; total += lasttotal;// 加上上次下载的总大小。 fis.close(); } conn.setrequestproperty("range", "bytes=" + startindex + "-" + endindex); conn.setconnecttimeout(5000); int code = conn.getresponsecode(); system.out.println("code=" + code); inputstream is = conn.getinputstream(); file file = new file("temp.exe"); randomaccessfile raf = new randomaccessfile(file, "rw"); // 指定文件开始写的位置。 raf.seek(startindex); system.out.println("第" + threadid + "个线程:写文件的开始位置:" + string.valueof(startindex)); int len = 0; byte[] buffer = new byte[512]; while ((len = is.read(buffer)) != -1) { randomaccessfile rf = new randomaccessfile(positionfile, "rwd"); raf.write(buffer, 0, len); total += len; rf.write(string.valueof(total).getbytes()); rf.close(); } is.close(); raf.close(); } catch (exception e) { e.printstacktrace(); } finally { // 只有所有的线程都下载完毕后 才可以删除记录文件。 synchronized (mutilethreaddownload.class) { system.out.println("线程" + threadid + "下载完毕了"); runningthreadcount--; if (runningthreadcount < 1) { system.out.println("所有的线程都工作完毕了。删除临时记录的文件"); for (int i = 1; i <= threadcount; i++) { file f = new file(i + ".txt"); system.out.println(f.delete()); } } } } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。