当前位置:首页 » JAVA技术教程

【Java】:多线程下载

2014-03-03 14:51 本站整理 浏览(7)

import java.io.InputStream;
 import java.io.RandomAccessFile;
 import java.net.URL;
 import java.net.URLConnection;
 
 public class MultithreadsDownload {
     public static void main(String[] args) {
         final int DOWNLOAD_THREAD_NUM = 4;
         final String FILE_NAME = "download.jpg";
         InputStream[] is = new InputStream[DOWNLOAD_THREAD_NUM];
         RandomAccessFile[] raf = new RandomAccessFile[DOWNLOAD_THREAD_NUM];
         
         try {
             URL url = new URL("http://p.qpic.cn/ninja/0/ninja1393807134/0");
             for (int i=0; i<DOWNLOAD_THREAD_NUM; i++) {
                 is[i] = url.openStream();
                 raf[i] = new RandomAccessFile(FILE_NAME, "rw");
             }
             long filelen = getFileLength(url);
             System.out.println("The size of the file is : " + filelen);
             //create a empty final file
             for (int i=0; i<filelen; i++)
                 raf[0].write(0);
             
             //compute the download size for per thread
             long numPerThread = filelen / DOWNLOAD_THREAD_NUM;
             long left = filelen % DOWNLOAD_THREAD_NUM;
             
             for (int i=0; i<DOWNLOAD_THREAD_NUM; i++) {
                 if (i == DOWNLOAD_THREAD_NUM-1)
                     new DownloadThread(i*numPerThread, (i+1)*numPerThread + left,
                             is[i], raf[i]).start();
                 else
                     new DownloadThread(i*numPerThread, (i+1)*numPerThread,
                             is[i], raf[i]).start();
             }
         } catch (Exception e)
         {
             e.printStackTrace();
         }
     }
     
     public static long getFileLength(URL url) throws Exception
     {
         URLConnection conn = url.openConnection();
         long size = conn.getContentLengthLong();
         return size;
     }
 }
 
 class DownloadThread extends Thread {
     
     DownloadThread(long start, long end, InputStream is, RandomAccessFile raf)
     {
         System.out.println("Begin downloading : " + start + "--->" + end);
         this.start = start;
         this.end = end;
         this.is = is;
         this.raf = raf;
     }
     
     @Override
     public void run()
     {
         try {
             //seek the appropriate input location of the cur thread
             is.skip(start);
             //seek the appropriate location for writing
             raf.seek(start);
             byte[] buff = new byte[BUFF_SIZE];
             long contentLen = end - start;
             //Ensure the totally download
             long times = contentLen / BUFF_SIZE + 4;
             int hasRead = 0;
             for (int i=0; i<times; i++) {
                 hasRead = is.read(buff);
                 if (hasRead < 0)
                     break;
                 raf.write(buff, 0, hasRead);
             }
         } catch (Exception e)
         {
             e.printStackTrace();
         }
         finally {
             try {
                 if (is != null)
                     is.close();
                 if (raf != null)
                     raf.close();
             }catch (Exception e)
             {
                 e.printStackTrace();
             }
         }
     }
     
     private final int BUFF_SIZE = 32;
     private long start;
     private long end;
     private InputStream is;
     private RandomAccessFile raf;
 }
作用JAVA实现对一个文件的多线程下载,基本思想是先读取文件大小,进行分块,创建多个线程分别负责某一部分的下载任务