本文以tomact 服务器 作介绍:
一:建一个 webproject,在Webroot 目录新建一个文件夹 用来存放下载的资源。
二:建立需要的包和类:
创建包:
在src下新建一个包用来存放下载的java类。
命名规范:
命名规范为公司名+java类的属性
如:bean 包 用来存放 实体 dao 包用来存放接口 util 存放工具 imp 包存放 接口的实现类; junit 包用来存放测试类。
由于本人以下代码只做讲解用,部分名称不规范请谅解;
三:设置加载下载的资源:
在 webroot目录下新建资源包,存放下载内容,本例资源名称为mg.avi;
四:代码介绍:
1. 下载的界面:
package download.util;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
public class DownloadJFrame extends JFrame {
// 声明组件
private JLabel downloadJLabel;
private JTextField downLoadJTextField;
private JButton downJButton;
private JLabel threadJLabel;
private JTextField threadJTextField;
// 声明 滚动条
private JProgressBar downloadJProgressBar;
public DownloadJFrame() {
// 设置标题
this.setTitle("下载工具");
this.setSize(400, 300);
// 设置居中显示
this.setLocationRelativeTo(null);
// 设置关闭时退出程序
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
// 获取面板的对象
Container c = this.getContentPane();
// 将面板的布局设置为空
c.setLayout(null);
// 实例化组件
downloadJLabel = new JLabel("下载地址:");
downLoadJTextField = new JTextField(
"http://localhost:8080/demo/res/mg.avi");
downJButton = new JButton("下载");
threadJLabel= new JLabel("线程数量");
threadJTextField=new JTextField("3");
downloadJProgressBar= new JProgressBar();
// 设置组件的位置
downloadJLabel.setBounds(20, 50, 70, 30);
downLoadJTextField.setBounds(95, 50, 260, 30);
threadJLabel.setBounds(20, 85, 70, 30);
threadJTextField.setBounds(95, 85, 260, 30);
downloadJProgressBar.setBounds(10, 130, 360, 10);
downJButton.setBounds(170, 150, 80, 30);
// 将组建添加到面板上
c.add(downloadJLabel);
c.add(downLoadJTextField);
c.add(downJButton);
c.add(downloadJProgressBar);
c.add(threadJLabel);
c.add(threadJTextField);
// 添加点击事件
downJButton.addActionListener(new MyactionListener());
this.setVisible(true);
}
public static void main(String[] args) {
new DownloadJFrame();
}
//声明一个内部类实现ActionListener
class MyactionListener implements ActionListener {
// 声明一个随机的文件
private RandomAccessFile accessFile;
@Override
public void actionPerformed(ActionEvent e) {
// 设置按钮不可用
downJButton.setEnabled(false);
// 获取下载的地址
final String path = downLoadJTextField.getText();
// 在指定的目录 创建 指定大小的文件 和类型
try {
// 根据路径创建url对象
URL url = new URL(path);
// 打开连接
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
// 设置请求头的方式
httpURLConnection.setRequestMethod("GET");
// 设置连接的超时时间
httpURLConnection.setConnectTimeout(5000);
// 设置请求的头像
httpURLConnection
.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.3; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
// System.out.println(httpURLConnection.getResponseCode());
// 获取下载文件的饿大小
int size = httpURLConnection.getContentLength();
// 根据下载的文件名称设置本地保存的文件
File file = new File("F:"
+ path.substring(path.lastIndexOf("/")));
// 根据文件创建出RnadomAccessFile 对象
accessFile = new RandomAccessFile(file, "rw");
// 设置文件的大小
accessFile.setLength(size);
// 关闭流
accessFile.close();
// 断开连接
httpURLConnection.disconnect();
String num= threadJTextField.getText();
int threadNum =Integer.parseInt(num);
System.out.println(threadNum);
// 定义线程的数量
for (int i = 1; i <= threadNum; i++) {
// 计算出每个线程下载的平均量(daxiao )
int blockSize = size / threadNum;
// 计算出每个线程开始下载的位置
int startSize = (i - 1) * blockSize;
// 计算出每个线程下载的结束的位置
int endSize = i * blockSize - 1;
if (i == threadNum) {
if (endSize < size) {
endSize = size;
}
}
// 文件随机读取的对象
RandomAccessFile threadFile = new RandomAccessFile(file,
"rw");
// 创建线程下载
new DownLoadThread(path, startSize, endSize, threadFile,downloadJProgressBar)
.start();
}
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
2. 所需线程的封装类:
package download.util;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.JProgressBar;
import org.xml.sax.InputSource;
public class DownLoadThread extends Thread {
// 下载的路径
private String path;
private int startSize;
private int endSize;
// 随机读取文件的对象
private RandomAccessFile threadFile;
//声明 滚动条
private JProgressBar downloadJProgressBar;
// 实例化
public DownLoadThread(String path, int startSize, int endSize,
RandomAccessFile threadFile, JProgressBar downloadJProgressBar) {
super();
this.path = path;
this.startSize = startSize;
this.endSize = endSize;
this.threadFile = threadFile;
this.downloadJProgressBar = downloadJProgressBar;
}
@Override
public void run() {
// 根据路径创建URl对象
try {
// 获取路径
URL url = new URL(path);
// 打开连接
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
// 设置请求的方式
httpURLConnection.setRequestMethod("GET");
// 设置连接的超时时间
httpURLConnection.setConnectTimeout(5000);
// 设置请求的头信息
httpURLConnection
.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.3; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
// 测试 用 输出
System.out.println(Thread.currentThread().getName() + "从----开始"
+ startSize + "下载。。。到----" + endSize + "结束");
//设置你读取的range 的范围
httpURLConnection.setRequestProperty("Range", "bytes="+startSize+"-"+endSize);
//获取输入流
InputStream is= httpURLConnection.getInputStream();
//设置文件开始写入的位置
threadFile.seek(startSize);
//缓冲区
byte buffer[]= new byte[1024];
//读取的长度
int len=0;
while((len=is.read(buffer))!=-1){
//获取进度条的值
int total=downloadJProgressBar.getValue();
//改变进度条
total+=len;
downloadJProgressBar.setValue(total);
//写入
threadFile.write(buffer, 0, len);
}
//释放资源
is.close();
threadFile.close();
httpURLConnection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
五:将工程发布到web服务器上,开启服务器;
六:运行效果:
只要下载地址服务器上存在,线程数可自定义,即可完成下载。