Java 如何实现多线程下载操作

来源:互联网 发布:知金教育是做什么的 编辑:程序博客网 时间:2024/04/27 23:55

本文以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;@Overridepublic 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 blocke1.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;}@Overridepublic 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服务器上,开启服务器;



六:运行效果:

 只要下载地址服务器上存在,线程数可自定义,即可完成下载。


原创粉丝点击