java实现多线程下载

  1. package donghongyujava.gui;
  2. import java.awt.event.ActionEvent;
  3. import java.awt.event.ActionListener;
  4. import java.io.File;
  5. import java.io.InputStream;
  6. import java.io.RandomAccessFile;
  7. import java.net.HttpURLConnection;
  8. import java.net.URL;
  9. import javax.swing.JButton;
  10. import javax.swing.JFrame;
  11. import javax.swing.JLabel;
  12. import javax.swing.JTextField;
  13. import javax.swing.plaf.InsetsUIResource;
  14. public class DownlodeJframe_v2 extends JFrame {
  15.     private JLabel downlodeJlabel;
  16.     private JTextField downlodeJTextField;
  17.     private JButton downlodeJButton;
  18.     public DownlodeJframe_v2() {
  19.         super(“下载页面”);
  20.         this.setLayout(null);
  21.         downlodeJlabel = new JLabel(“下载连接:”);
  22.         downlodeJlabel.setBounds(20, 30, 80, 30);
  23.         downlodeJTextField = new JTextField(
  24.                 “http://172.22.65.22:8080/day31/vedio/test.rmvb”);
  25.         downlodeJTextField.setBounds(90, 30, 350, 30);
  26.         downlodeJButton = new JButton(“立即下载”);
  27.         downlodeJButton.setMargin(new InsetsUIResource(0, 0, 0, 0));
  28.         downlodeJButton.setBounds(200, 120, 100, 40);
  29.         add(downlodeJlabel);
  30.         add(downlodeJTextField);
  31.         add(downlodeJButton);
  32.         downlodeJButton.addActionListener(new MyActionListener());
  33.         this.setSize(500, 300);
  34.         this.setLocationRelativeTo(null);
  35.         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  36.         this.setVisible(true);
  37.     }
  38.     public static void main(String[] args) {
  39.         new DownlodeJframe_v2();
  40.     }
  41.     // 事件监听的内部类
  42.     class MyActionListener implements ActionListener {
  43.         // 声明随机访问的随机访问文件
  44.         private RandomAccessFile access;
  45.         @Override
  46.         public void actionPerformed(ActionEvent e) {
  47.             // TODO Auto-generated method stub
  48.             // 设置按钮不可用
  49.             downlodeJButton.setEnabled(false);
  50.             // 获取下载链接
  51.             final String path = downlodeJTextField.getText();
  52.             try {
  53.                 // 根据路径创建url对象的对象
  54.                 URL url = new URL(path);
  55.                 // HttpURLConnection支持 HTTP 特定功能的 URLConnection。
  56.                 /*
  57.                  * 每个 HttpURLConnection 实例都可用于生成单个请求, 但是其他实例可以透明地共享连接到 HTTP
  58.                  * 服务器的基础网络。 请求后在 HttpURLConnection 的 InputStream 或 OutputStream
  59.                  * 上 调用 close() 方法可以释放与此实例关联的网络资源, 但对共享的持久连接没有任何影响。如果在调用
  60.                  * disconnect() 时持久连接空闲,则可能关闭基础套接字。
  61.                  */
  62.                 // 调用url中的openConnection(Proxy proxy)与 openConnection() 类似,
  63.                 // 所不同是连接通过指定的代理建立;不支持代理方式的协议处理程序将忽略该代理参数并建立正常的连接。
  64.                 HttpURLConnection httpURLConnection = (HttpURLConnection) url
  65.                         .openConnection();
  66.                 // 获取目标资源的大小
  67.                 int size = httpURLConnection.getContentLength();
  68.                 // 获取目标资源的名称并设置对应的保存名称
  69.                 // substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串
  70.                 // /该子字符串从指定索引处的字符开始,直到此字符串末尾。
  71.                 // lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的索引。
  72.                 File file = new File(“E:”
  73.                         + path.substring(path.lastIndexOf(“/”)));
  74.                 // 根据文件的名称创建出RandomAccessFile此类的实例支持对随机访问文件的读取和写入。
  75.                 // RandomAccessFile(File file, String mode) 创建从中读取和向其中写入
  76.                 // (可选)的随机访问文件流,该文件由 File 参数指定。
  77.                 // mode取值:
  78.                 /*
  79.                  * 值 含意
  80.                  *
  81.                  * “r” 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。 “rw”
  82.                  * 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。 “rws” 打开以便读取和写入,对于
  83.                  * “rw”,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。 “rwd” 打开以便读取和写入,对于
  84.                  * “rw”,还要求对文件内容的每个更新都同步写入到底层存储设备。
  85.                  */
  86.                 access = new RandomAccessFile(file, “rw”);
  87.                 // 设置文件的大小
  88.                 access.setLength(size);
  89.                 // 关闭此随机访问文件流并释放与该流关联的所有系统资源。
  90.                 access.close();
  91.                 // 指示近期服务器不太可能有其他请求。
  92.                 httpURLConnection.disconnect();
  93.                 // 定义线程的数量
  94.                 int threadNumber = 3;
  95.                 // 向创建出来的与目标文件大小及类型相同的文件中写入数据
  96.                 for (int i = 1; i <= threadNumber; i++) {
  97.                     // 根据目标资源的总大小计算每条线程所需要分担的下载大小
  98.                     int blockSize = size / threadNumber;
  99.                     // 计算出每条线程的开始下载位置
  100.                     final int startSize = (i – 1) * blockSize;
  101.                     int temp = i * blockSize – 1;
  102.                     // 判断当前运行的线程是不是最后一条
  103.                     if (i == threadNumber) {
  104.                         if (temp < size) {
  105.                             temp = size;
  106.                         }
  107.                     }
  108.                     // 计算线程下载的结束位置
  109.                     final int endSize = temp;
  110.                     // 创建线程内部的文件随机读取的对象
  111.                     final RandomAccessFile threadFile = new RandomAccessFile(file,
  112.                             “rw”);
  113.                     // 创建线程
  114.                     new Thread() {
  115.                         public void run() {
  116.                             // 创建与资源文件的在一次连接
  117.                             try {
  118.                                 // 根据目标资源的路径创建url对象
  119.                                 URL url = new URL(path);
  120.                                 // 打开链接
  121.                                 HttpURLConnection httpURLConnection = (HttpURLConnection) url
  122.                                         .openConnection();
  123.                                 // 设置一般请求属性。
  124.                                 httpURLConnection.setRequestProperty(“Range”,
  125.                                         “bytes=” + startSize + “-” + endSize);
  126.                                 // 获取连接后的输入流对象
  127.                                 InputStream is = httpURLConnection
  128.                                         .getInputStream();
  129.                                 // 设置文件开始写入的位置
  130.                                 threadFile.seek(startSize);
  131.                                 //缓冲区创建
  132.                                 byte buffer[]=new byte[1024];
  133.                                 //读取文件长度
  134.                                 int len=0;
  135.                                 while((len=is.read(buffer))!=-1){
  136.                                     threadFile.write(buffer, 0, len);
  137.                                 }
  138.                                 //释放资源
  139.                                 is.close();
  140.                                 threadFile.close();
  141.                                 httpURLConnection.disconnect();
  142.                             } catch (Exception e) {
  143.                                 // TODO Auto-generated catch block
  144.                                 e.printStackTrace();
  145.                             }
  146.                         }
  147.                     }.start();
  148.                 }
  149.             } catch (Exception e1) {
  150.                 // TODO Auto-generated catch block
  151.                 e1.printStackTrace();
  152.             }
  153.         }
  154.     }
  155. }

标签