歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java多線程下載輔助類實現

Java多線程下載輔助類實現

日期:2017/3/1 10:16:44   编辑:Linux編程

使用聲明:

類名:MultiThreadDownloadUtil

API:

(1)download(String path,int count);

path:文件URL;

count:線程數量;

  1. package org.xiazdong.multidownload.util;
  2. import java.io.File;
  3. import java.io.InputStream;
  4. import java.io.RandomAccessFile;
  5. import java.net.HttpURLConnection;
  6. import java.net.URL;
  7. public class MultiThreadDownloadUtil{
  8. private static int filesize;
  9. private static int block;
  10. private static String filename;
  11. private static int downloadsize;
  12. private class MyThread extends Thread{
  13. private int i; //線程ID
  14. private String path; //下載文件的URL
  15. public MyThread(int i, String path) {
  16. this.i = i;
  17. this.path = path;
  18. downloadsize = 0;
  19. }
  20. @Override
  21. public void run() {
  22. try{
  23. System.out.println("線程"+(i+1)+"開始下載");
  24. //1.打開文件,並定位位置
  25. RandomAccessFile raf = new RandomAccessFile(new File(filename), "rwd");
  26. raf.seek(i*block); //定位到此線程要負責下載的位置
  27. int start = i*block;
  28. int end = (i+1)*block-1;
  29. //2.連接服務器
  30. URL url = new URL(path);
  31. HttpURLConnection conn = (HttpURLConnection)url.openConnection();
  32. conn.setRequestMethod("GET");
  33. conn.setRequestProperty("range", "bytes="+start+"-"+end); //發出請求頭
  34. if(conn.getResponseCode()==206){ //注意:分段下載的返回碼為206,而不是200
  35. InputStream in = conn.getInputStream();
  36. int length = 0;
  37. byte[]data = new byte[1024];
  38. while((length=in.read(data))!=-1){
  39. raf.write(data,0,length); //寫入本地文件
  40. }
  41. }
  42. //顯示下載進度
  43. downloadsize += (end-start);
  44. System.out.println("已下載"+downloadsize/1024.0+"k,共"+filesize/1024.0+"k");
  45. //3.關閉文件
  46. raf.close();
  47. System.out.println("線程"+(i+1)+"結束下載...");
  48. }
  49. catch(Exception e){
  50. e.printStackTrace();
  51. }
  52. }
  53. }
  54. /**
  55. * 下載文件
  56. * @param path URL
  57. * @param threadcount 線程數
  58. * @throws Exception
  59. */
  60. public static void download(String path,int threadcount) throws Exception{
  61. filename = path.substring(path.lastIndexOf('/')+1);
  62. filesize = getFileSize(path);
  63. block = getBlockSize(filesize,threadcount);
  64. createLocalRandomFile(filesize);
  65. MultiThreadDownloadUtil mdu = new MultiThreadDownloadUtil();
  66. for(int i=0;i<threadcount;i++){
  67. mdu.new MyThread(i,path).start();
  68. }
  69. }
  70. /**
  71. * 創建一個本地文件,並設置文件的大小
  72. * @param filesize
  73. * @throws Exception
  74. */
  75. private static void createLocalRandomFile(int filesize) throws Exception {
  76. RandomAccessFile raf = new RandomAccessFile(new File(filename), "rwd");
  77. raf.setLength(filesize);
  78. raf.close();
  79. }
  80. /**
  81. * 根據文件總大小和線程數求出每個線程要下載的數據量
  82. * @param filesize
  83. * @param threadcount
  84. * @return
  85. */
  86. private static int getBlockSize(int filesize, int threadcount) {
  87. return filesize%threadcount==0?filesize/threadcount:(filesize/threadcount+1);
  88. }
  89. /**
  90. * 求出文件總大小
  91. * @param path
  92. * @return
  93. * @throws Exception
  94. */
  95. private static int getFileSize(String path) throws Exception{
  96. URL url = new URL(path);
  97. HttpURLConnection conn = (HttpURLConnection)url.openConnection();
  98. conn.setRequestMethod("GET");
  99. if(conn.getResponseCode()==200){
  100. return conn.getContentLength();
  101. }
  102. else{
  103. return 0;
  104. }
  105. }
  106. }

測試類:

  1. package org.xiazdong.download;
  2. import org.xiazdong.multidownload.util.MultiThreadDownloadUtil;
  3. public class MultiThreadDownloader {
  4. public static void main(String[] args) throws Exception {
  5. int threadCount = 3; //指定線程數量
  6. String path = "http://dlc2.pconline.com.cn/filedown_61761_6694063/drivethelife2010_pconline_setup.exe"; //指定下載文件路徑
  7. MultiThreadDownloadUtil.download(path, threadCount);
  8. }
  9. }

將此文件下載到工程目錄後,運行可用;

Copyright © Linux教程網 All Rights Reserved