【Java】:多线程下载

  1 import java.io.InputStream;
  2 import java.io.RandomAccessFile;
  3 import java.net.URL;
  4 import java.net.URLConnection;
  5 
  6 public class MultithreadsDownload {
  7     public static void main(String[] args) {
  8         final int DOWNLOAD_THREAD_NUM = 4;
  9         final String FILE_NAME = "download.jpg";
 10         InputStream[] is = new InputStream[DOWNLOAD_THREAD_NUM];
 11         RandomAccessFile[] raf = new RandomAccessFile[DOWNLOAD_THREAD_NUM];
 12         
 13         try {
 14             URL url = new URL("http://p.qpic.cn/ninja/0/ninja1393807134/0");
 15             for (int i=0; i<DOWNLOAD_THREAD_NUM; i++) {
 16                 is[i] = url.openStream();
 17                 raf[i] = new RandomAccessFile(FILE_NAME, "rw");
 18             }
 19             long filelen = getFileLength(url);
 20             System.out.println("The size of the file is : " + filelen);
 21             //create a empty final file
 22             for (int i=0; i<filelen; i++)
 23                 raf[0].write(0);
 24             
 25             //compute the download size for per thread
 26             long numPerThread = filelen / DOWNLOAD_THREAD_NUM;
 27             long left = filelen % DOWNLOAD_THREAD_NUM;
 28             
 29             for (int i=0; i<DOWNLOAD_THREAD_NUM; i++) {
 30                 if (i == DOWNLOAD_THREAD_NUM-1)
 31                     new DownloadThread(i*numPerThread, (i+1)*numPerThread + left,
 32                             is[i], raf[i]).start();
 33                 else
 34                     new DownloadThread(i*numPerThread, (i+1)*numPerThread,
 35                             is[i], raf[i]).start();
 36             }
 37         } catch (Exception e)
 38         {
 39             e.printStackTrace();
 40         }
 41     }
 42     
 43     public static long getFileLength(URL url) throws Exception
 44     {
 45         URLConnection conn = url.openConnection();
 46         long size = conn.getContentLengthLong();
 47         return size;
 48     }
 49 }
 50 
 51 class DownloadThread extends Thread {
 52     
 53     DownloadThread(long start, long end, InputStream is, RandomAccessFile raf)
 54     {
 55         System.out.println("Begin downloading : " + start + "--->" + end);
 56         this.start = start;
 57         this.end = end;
 58         this.is = is;
 59         this.raf = raf;
 60     }
 61     
 62     @Override
 63     public void run()
 64     {
 65         try {
 66             //seek the appropriate input location of the cur thread
 67             is.skip(start);
 68             //seek the appropriate location for writing
 69             raf.seek(start);
 70             byte[] buff = new byte[BUFF_SIZE];
 71             long contentLen = end - start;
 72             //Ensure the totally download
 73             long times = contentLen / BUFF_SIZE + 4;
 74             int hasRead = 0;
 75             for (int i=0; i<times; i++) {
 76                 hasRead = is.read(buff);
 77                 if (hasRead < 0)
 78                     break;
 79                 raf.write(buff, 0, hasRead);
 80             }
 81         } catch (Exception e)
 82         {
 83             e.printStackTrace();
 84         }
 85         finally {
 86             try {
 87                 if (is != null)
 88                     is.close();
 89                 if (raf != null)
 90                     raf.close();
 91             }catch (Exception e)
 92             {
 93                 e.printStackTrace();
 94             }
 95         }
 96     }
 97     
 98     private final int BUFF_SIZE = 32;
 99     private long start;
100     private long end;
101     private InputStream is;
102     private RandomAccessFile raf;
103 }

作用JAVA实现对一个文件的多线程下载,基本思想是先读取文件大小,进行分块,创建多个线程分别负责某一部分的下载任务

posted @ 2014-03-03 14:51  sangoly  阅读(209)  评论(0编辑  收藏  举报