【问题】关于从网上下载一个文件分多个线程同时下载。
主要使用到HttpURLConnection对象的setRequestProperty(String key,String value);
方法简单说一下如何使用,setRequestProperty()方法严格上讲是HttpURLConnection的父类—URLConnection的方法,而URL.openConnection()返回的是一个URLConnection
对象,而一般我们都用他的子类HttpURLConnection去做链接和网络传输工作。
【解决思路总述】
1,把指定文件(通过HttpURLConnection.getContentLength();获得文件大小),分成指定线程数下载,或者指定每个线程承担下载任务的大小(再次我们仅以后者分析)
2,计算所需线程数
3,将获得的数据保存本地(使用RandomAccessFile流存储)
【代码】
package com.wsf.demo;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class ImageDownload {
public final static String sate = "http://www.baidu.com/img/bd_logo1.png";//本题所下载的文件是一个百度图标
public static void main(String[] args) {
try {
//创建一个URL对象
URL url = new URL(sate);
//建立一个链接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//制定相应方式
conn.setRequestMethod("GET");
//进行连接
conn.connect();
//获得响应码
int code = conn.getResponseCode();
//获得文件名字
int position = sate.lastIndexOf("/");
String fileName = sate.substring(position+1);
System.out.println("服务器响应码:"+code);
//如果响应码是200 则链接下载。。。
if(code == HttpURLConnection.HTTP_OK){
//获得文件长度
int contentLength = conn.getContentLength();
System.out.println("文件总长度:"+contentLength);
//设定想要启动下载线程,用于把文件分成多少分进行下载
RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd");
raf.setLength(contentLength);
raf.close();
//假定每个线程负责下载的长度为1k
int blockSize = 1024*2;
//如果能除尽指定线程数 否则线程数+1
int size = contentLength%blockSize==0 ? contentLength/blockSize : (contentLength/blockSize)+1;
for(int i = 0;i<size;i++){
if(i==(size-1)){
new DownLoadThread(i, (contentLength-(blockSize*i)), fileName,contentLength).start();
System.out.println("启动了第:"+i+" 线程---------------------"+(contentLength-(blockSize*i)));
return;
}
new DownLoadThread(i, blockSize, fileName,(i+1)*blockSize).start();
System.out.println("启动了第:"+i+" 线程---------------------"+blockSize);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class DownLoadThread extends Thread{
private int fileCount;
private int blockSize;
private String fileName;
private int TotalLength;
public DownLoadThread(int fileCount,int blockSize,String fileName,int TotalLength){
this.fileCount = fileCount;
this.blockSize = blockSize;
this.fileName = fileName;
this.TotalLength= TotalLength;
}
@Override
public void run() {
try {
URL url = new URL(ImageDownload.sate);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes="+(TotalLength-blockSize)+"-"+(TotalLength));
conn.connect();
System.out.println(fileCount+"开始:"+(TotalLength-blockSize)+",结束:"+TotalLength);
//多线程同时下载文件,因此要使用随机访问文件流,即同时写入读取,seek(int index)制定存放的位置
RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd");
raf.seek(TotalLength-blockSize);
int code = conn.getResponseCode();
System.out.println(fileCount+">>>Code>>>"+code);
if(code == HttpURLConnection.HTTP_OK || code == 206){
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
int len = 0;
byte[]buf = new byte[1024];
while((len = bis.read(buf,0,buf.length))!=-1){
raf.write(buf, 0, len);
System.out.println(fileCount+"下载长度:"+len);
}
//回收资源
raf.close();
System.out.println("第"+fileCount+"段下载完毕!!!");
return;
}
System.out.println("第"+fileCount+"段下载失败!!!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
今天的文章HttpURLConnection方法之setRequestProperty()浅谈分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/24041.html