import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
/**
* 下载程序的主类,本身不负责下载,而是负责获取远程文件的尺寸,然后决定开启多少个
* 下载线程(DownloadThread),进而为每一个下载线程分配下载任务(实际就是向每个
* 下载线程传入下载偏移量、下载字节数等参数)
*
*/
public class DownloadManager {
static final long unitSize = 100 * 1024;// 分配给每个线程的下载字节数,常量
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入要下在的文件的url:");
String remoteFileUrl = sc.next();
System.out.println("请输入该文件存储的本地磁盘路径:");
String localFileName = sc.next();
System.out.println("URL="+remoteFileUrl);
System.out.println("address="+localFileName);
new DownloadManager().doDownload(remoteFileUrl, localFileName);
}
/**
*
* @param remoteFileUrl
* 远程被下载文件名
* @param localFileName
* 本地存储文件名
* @throws IOException
* 此方法的作用是首先获得远程文件的尺寸信息(发送HTTP的HEAD请求), 然后根据
* 文件尺寸的大小分配合适的线程数进行下载
*/
public void doDownload(String remoteFileUrl, String localFileName)
throws IOException {
//获取远程文件尺寸
long fileSize = this.getRemoteFileSize(remoteFileUrl);
//在本地磁盘创建同大小的文件用于存储
this.createFile(localFileName, fileSize);
//根据文件尺寸分配线程个数
long threadCount = fileSize/unitSize;
if(fileSize%unitSize!=0) {
threadCount++;
}
System.out.println("被下载文件大小为:"+fileSize+"字节,需要启动"+threadCount+"个线程");
long offset = 0;//记录下载文件的偏移量
// if(fileSize<=unitSize) { //文件的尺寸小于unitSize,则启动一个线程进行下载
// DownloadThread downloadThread = new DownloadThread(remoteFileUrl,
// localFileName,offset,fileSize);
// downloadThread.start();
// }else {//文件尺寸大于unitSize,则需要启动threadCount个线程来进行下载
// for(int i=0;i<threadCount;i++) {
// DownloadThread downloadThread = new DownloadThread(remoteFileUrl,
// localFileName,offset,unitSize);
// offset = offset + unitSize;
// }
// }
for(int i=1;i<threadCount;i++) {
DownloadThread downloadThread = new DownloadThread(remoteFileUrl,
localFileName,offset,unitSize);
downloadThread.start();
offset = offset + unitSize;
}
DownloadThread downloadThread = new DownloadThread(remoteFileUrl,
localFileName,offset,fileSize-unitSize*(threadCount-1));
downloadThread.start();
}
/**
* 获取一个远程文件的尺寸
*
* @param fileName
* @return
*/
private long getRemoteFileSize(String fileName) throws IOException {
long fileSize = 0;
// 创建HTTP连接
HttpURLConnection httpConnection = (HttpURLConnection) new URL(fileName)
.openConnection();
// 发送HEAD请求
httpConnection.setRequestMethod("HEAD");
/*
* 获取服务器端返回的数据,从中取得文件的尺寸信息 因为不知道服务器是tomcat还是iis或者
* 其他,所以无法知道Content-Length数据项在什么位置,所以需要对每个数据项进行匹配,
* 又因为一般头信息少于10个数据项,所以用10进行循环判断
*/
for (int i = 1; i <= 10; i++) {
System.out.println("报文头:"+httpConnection.getHeaderField(i));
if(httpConnection.getHeaderFieldKey(i).equalsIgnoreCase("Content-Length")) {
fileSize = Long.parseLong(httpConnection.getHeaderField(i));
return fileSize;
}
}
return fileSize;
}
/**
* 在本地磁盘中创建一个文件来存储要下载的数据
*
* @param fileName
* @param fileSize
* @throws IOException
*/
private void createFile(String fileName, long fileSize) throws IOException {
File file = new File(fileName);
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.setLength(fileSize);
raf.close();
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
java写的多线程下载程序源码
共4个文件
java:2个
classpath:1个
project:1个
5星 · 超过95%的资源 需积分: 9 54 下载量 3 浏览量
2010-06-25
12:53:54
上传
评论 1
收藏 4KB RAR 举报
温馨提示
利用java多线程以及网络编程知识写的一个下载程序源码,程序根据被下载文件的大小启动相应个数的线程对其进行下载。
资源推荐
资源详情
资源评论
收起资源包目录
download.rar (4个子文件)
download
.classpath 226B
DownloadThread.java 3KB
DownloadManager.java 4KB
.project 384B
共 4 条
- 1
资源评论
- wu183573520762014-12-14不错,可以用,借鉴学习
- u0108844352013-06-24很实用 不错 很强大
- sinat_281992392015-05-17很不错,可以学习一下多线程
- 北海宇微2013-04-29不错 可以用
- gaohaozx2013-06-28不错不错,可以用哦
silenceasd
- 粉丝: 1
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功