1 importjava.io.BufferedReader;2 importjava.io.File;3 importjava.io.FileInputStream;4 importjava.io.FileOutputStream;5 importjava.io.IOException;6 importjava.io.InputStream;7 importjava.io.InputStreamReader;8 importjava.io.RandomAccessFile;9 importjava.net.HttpURLConnection;10 importjava.net.URL;11

12 importjavax.print.attribute.standard.Finishings;13

14 public classMultiDownload {15

16 static int ThreadCount = 3;17 static int finishedThread = 0;18 //确定下载地址

19 static String path = "http://192.168.13.13:8080/QQPlayer.exe";20 public static voidmain(String[] args) {21

22 //发送get请求,请求这个地址的资源

23 try{24 URL url = newURL(path);25 HttpURLConnection conn =(HttpURLConnection) url.openConnection();26 conn.setRequestMethod("GET");27 conn.setConnectTimeout(5000);28 conn.setReadTimeout(5000);29

30 if(conn.getResponseCode() == 200){31 //拿到所请求资源文件的长度

32 int length =conn.getContentLength();33

34 File file = new File("QQPlayer.exe");35 //生成临时文件

36 RandomAccessFile raf = new RandomAccessFile(file, "rwd");37 //设置临时文件的大小

38 raf.setLength(length);39 raf.close();40 //计算出每个线程应该下载多少字节

41 int size = length /ThreadCount;42

43 for (int i = 0; i < ThreadCount; i++) {44 //计算线程下载的开始位置和结束位置

45 int startIndex = i *size;46 int endIndex = (i + 1) * size - 1;47 //如果是最后一个线程,那么结束位置写死

48 if(i == ThreadCount - 1){49 endIndex = length - 1;50 }51 //System.out.println("线程" + i + "的下载区间是:" + startIndex + "---" + endIndex);

52 newDownLoadThread(startIndex, endIndex, i).start();53 }54 }55 } catch(Exception e) {56 //TODO Auto-generated catch block

57 e.printStackTrace();58 }59 }60

61

62 }63 class DownLoadThread extendsThread{64 intstartIndex;65 intendIndex;66 intthreadId;67

68 public DownLoadThread(int startIndex, int endIndex, intthreadId) {69 super();70 this.startIndex =startIndex;71 this.endIndex =endIndex;72 this.threadId =threadId;73 }74

75 @Override76 public voidrun() {77 //再次发送http请求,下载原文件

78 try{79 File progressFile = new File(threadId + ".txt");80 //判断进度临时文件是否存在

81 if(progressFile.exists()){82 FileInputStream fis = newFileInputStream(progressFile);83 BufferedReader br = new BufferedReader(newInputStreamReader(fis));84 //从进度临时文件中读取出上一次下载的总进度,然后与原本的开始位置相加,得到新的开始位置

85 startIndex +=Integer.parseInt(br.readLine());86 fis.close();87 }88 System.out.println("线程" + threadId + "的下载区间是:" + startIndex + "---" +endIndex);89 HttpURLConnection conn;90 URL url = newURL(MultiDownload.path);91 conn =(HttpURLConnection) url.openConnection();92 conn.setRequestMethod("GET");93 conn.setConnectTimeout(5000);94 conn.setReadTimeout(5000);95 //设置本次http请求所请求的数据的区间

96 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" +endIndex);97

98 //请求部分数据,相应码是206

99 if(conn.getResponseCode() == 206){100 //流里此时只有1/3原文件的数据

101 InputStream is =conn.getInputStream();102 byte[] b = new byte[1024];103 int len = 0;104 int total = 0;105 //拿到临时文件的输出流

106 File file = new File("QQPlayer.exe");107 RandomAccessFile raf = new RandomAccessFile(file, "rwd");108 //把文件的写入位置移动至startIndex

109 raf.seek(startIndex);110 while((len = is.read(b)) != -1){111 //每次读取流里数据之后,同步把数据写入临时文件

112 raf.write(b, 0, len);113 total +=len;114 //System.out.println("线程" + threadId + "下载了" + total);115

116 //生成一个专门用来记录下载进度的临时文件

117 RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd");118 //每次读取流里数据之后,同步把当前线程下载的总进度写入进度临时文件中

119 progressRaf.write((total + "").getBytes());120 progressRaf.close();121 }122 System.out.println("线程" + threadId + "下载完毕-------------------小志参上!");123 raf.close();124

125 MultiDownload.finishedThread++;126 synchronized(MultiDownload.path) {127 if(MultiDownload.finishedThread ==MultiDownload.ThreadCount){128 for (int i = 0; i < MultiDownload.ThreadCount; i++) {129 File f = new File(i + ".txt");130 f.delete();131 }132 MultiDownload.finishedThread = 0;133 }134 }135

136 }137 } catch(Exception e) {138 //TODO Auto-generated catch block

139 e.printStackTrace();140 }141 }142 }

Logo

GitCode AI社区是一款由 GitCode 团队打造的智能助手,AI大模型社区、提供国内外头部大模型及数据集服务。

更多推荐