肯定比放10毫秒的水要多。
多线程下载的实现过程:
1>首先得到下载文件的长度,然后设置本地文件
的长度。
RandomAccessFile file = new RandomAccessFile("QQWubiSetup.exe","rwd");
3>使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,如:指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止,代码如下:
4>保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。
threadfile.seek(2097152);//从文件的什么位置开始写入数据
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class ThreadDowmLoad {
public static void main(String[] args) {
String path = "http://file1.51cto.com/index.php?aid=785088&k=205dfb403540e1ee182fd48c80247ab6&t=1347439680";
int threadNum = 3;
try {
new ThreadDowmLoad().downLoad(path, threadNum);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 从路径中获取下载文件名称
*
* @param path下载文件的路径
* @return 最后一个"/"后面字段的内容作为下载后的文件名
*/
public static String getFileName(String path) {
// 获得最后一个"/"后面字段的内容作为下载后的文件名
return path.substring(path.lastIndexOf("/") + 1);
}
/**
* @param path下载文件的路径
* @param threadNum线程数
* @throws Exception
*/
public void downLoad(String path, int threadNum) throws Exception {
URL url = new URL(path);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
// 得到httpURLConnection对象进行相关设置
// 设置请求方式
httpURLConnection.setRequestMethod("GET");
// 设置链接超时时间
httpURLConnection.setConnectTimeout(5 * 1000);
// 通过getContentLength()取得下载长度
int downloadLength = httpURLConnection.getContentLength();
// 生成同长度的本地文件,存放下载数据-----RandomAccessFile随机文件访问类
String fileName = getFileName(path);// 从路径中获取下载文件名称
// 通过相对路径将下载后的文件保存到根目录中
File saveFile = new File(fileName);
// "rwd"表示同步将文件下载到指定路径中,没有缓存,若没有“d”则会有缓存不同步
RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile,
"rwd");
// 保存在本地的文件长度=网络下载的文件长度
randomAccessFile.setLength(downloadLength);
randomAccessFile.close();
// 计算每条线程下载的数据长度
int block = downloadLength % threadNum == 0 ? (downloadLength / threadNum)
: (downloadLength / threadNum) + 1;
// 计算每条线程开始下载与结束下载的位置
for (int i = 0; i < threadNum; i++) {
// 开线程下载各自的数据段
new DownLoadThread(url, saveFile, block, threadNum).start();
}
}
/**
*
* @author YanJun URL url, 路径 File saveFile,文件名 int block, 数据段长度 int
* threadNum 指定线程
*/
private final class DownLoadThread extends Thread {
private URL url;
private File saveFile;
private int block;
private int threadNum;
public DownLoadThread(URL url, File saveFile, int block, int threadNum) {
super();
this.url = url;
this.saveFile = saveFile;
this.block = block;
this.threadNum = threadNum;
}
@Override
public void run() {
// 计算下载文件数据的开始和结束位置
int startPosition = threadNum * block;
int endPosition = (threadNum + 1) * block - 1;
try {
// 随机文件访问类
RandomAccessFile randomAccessFile = new RandomAccessFile(
saveFile, "rwd");
// 从什么位置访问数据randomAccessFile.seek(startPosition);
randomAccessFile.seek(startPosition);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
// 得到httpURLConnection对象进行相关设置
// 设置请求方式
httpURLConnection.setRequestMethod("GET");
// 设置链接超时时间
httpURLConnection.setConnectTimeout(5 * 1000);
// 使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,如:指定从文件的2M位置开始下载
httpURLConnection.setRequestProperty("Range", "bytes="
+ startPosition + "-" + endPosition);
// 取得输入流
InputStream inputStream = httpURLConnection.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;// 当len=-1,表示流读取完毕
// inputStream.read(buffer)--从输入流里读取数据到缓冲区
while ((len = inputStream.read(buffer)) != -1) {
randomAccessFile.write(buffer, 0, len);
}
inputStream.close();
randomAccessFile.close();
System.out.println(threadNum + "号下载完成");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}