為父母生,為老婆死,為程序奮斗一輩子,吃眼前虧,上公司的當(dāng),最后死在客戶的需求上

          Hector_封嘴

          華子說(shuō):看破紅塵,與程序?yàn)榘椋?
          posts - 4, comments - 1, trackbacks - 0, articles - 1
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          Java多線程下載文件

          Posted on 2012-10-23 06:52 赫赫 閱讀(286) 評(píng)論(0)  編輯  收藏 所屬分類: J2EE
          文件下載采用多線程方式能夠充分利用CPU資源,關(guān)鍵點(diǎn)是設(shè)置線程的讀取開(kāi)始和結(jié)束位置。下面的代碼,采用線程池啟動(dòng)10個(gè)線程來(lái)執(zhí)行下載
          import java.io.BufferedInputStream;
          import java.io.IOException;
          import java.io.RandomAccessFile;
          import java.net.HttpURLConnection;
          import java.net.URL;
          import java.net.URLConnection;
          import java.util.concurrent.CountDownLatch;
          import java.util.concurrent.ExecutorService;
          import java.util.concurrent.Executors;


          public class FileDownLoadTest {
              
              
              
          private static final int TCOUNT = 10;
              
              
          private CountDownLatch latch = new CountDownLatch(TCOUNT);

              
          private long completeLength = 0;
              
              
          private long fileLength;
              
          /**
               * 
          @param args
               * 
          @throws Exception 
               
          */

              
          public static void main(String[] args) throws Exception {
                  
                  
          new FileDownLoadTest().download("http://localhost:8080/test/IESSAction.docx");
              }

              
              
              
          public void download(String address) throws Exception{
                  ExecutorService service 
          = Executors.newFixedThreadPool(TCOUNT);
                  URL url 
          = new URL(address);
                  URLConnection cn 
          = url.openConnection();
                  cn.setRequestProperty(
          "Referer""http://www.test.com");
                  fileLength 
          = cn.getContentLength();
                  
          long packageLength = fileLength/TCOUNT;
                  
          long leftLength = fileLength%TCOUNT;
                  RandomAccessFile file 
          = new RandomAccessFile("d:\\test.docx","rw");
                  
          //計(jì)算每個(gè)線程請(qǐng)求文件的開(kāi)始和結(jié)束位置
                  long pos = 0;
                  
          long endPos = pos + packageLength;
                  
          for(int i=0; i<TCOUNT; i++){
                      
          if(leftLength >0){
                          endPos 
          ++;
                          leftLength
          --;
                      }

                      service.execute(
          new DownLoadThread(url, file, pos, endPos));
                      pos 
          = endPos;
                      endPos 
          = pos + packageLength;
                  }

                  System.out.println(
          "waiting.");
                  
          long begin = System.currentTimeMillis();
                  latch.await();
                  file.close();
                  System.out.println(
          "end.");
                  System.out.println(System.currentTimeMillis() 
          - begin + "ms");
                  service.shutdown();
              }

              
              
          class DownLoadThread implements Runnable{
                  
                  
          private URL url;
                  
          private RandomAccessFile file;
                  
          private long from;
                  
          private long end;
                  
                  DownLoadThread(URL url, RandomAccessFile file, 
          long from, long end){
                      
          this.url = url;
                      
          this.file = file;
                      
          this.from = from;
                      
          this.end = end;
                  }

                  
                  
                  
          public void run() {
                      
          long pos = from;
                      
          byte[] buf = new byte[512];
                      
          try {
                          HttpURLConnection cn 
          = (HttpURLConnection) url.openConnection();
                          cn.setRequestProperty(
          "Range""bytes=" + from + "-" + end);
                          
          if(cn.getResponseCode() != 200 && cn.getResponseCode()!=206){
                              run();
                              
          return;
                          }

                          BufferedInputStream bis 
          = new BufferedInputStream(cn.getInputStream());
                          
          int len ;
                          
          while((len = bis.read(buf)) != -1){
          //                    synchronized(file){
                                  file.seek(pos);
                                  file.write(buf, 
          0, len);
          //                    }
                              pos += len;
                              completeLength 
          +=len;
                              System.out.println(
          "threadName: " + Thread.currentThread().getName() 
                                      
          + "persent: " + completeLength * 100 /fileLength + "%");
                          }

                          cn.disconnect();
                          latch.countDown();
                      }
           catch (IOException e) {
                          e.printStackTrace();
                          
                      }

                  }

              }

          }


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          用兩年的工作經(jīng)驗(yàn),從零開(kāi)始,重新開(kāi)始做一個(gè)稱職的程序員!
          主站蜘蛛池模板: 金山区| 潮州市| 师宗县| 射阳县| 武夷山市| 繁峙县| 栾川县| 新绛县| 甘洛县| 海宁市| 南投市| 武鸣县| 大荔县| 比如县| 皋兰县| 庆城县| 甘肃省| 三台县| 岱山县| 新绛县| 甘洛县| 蒙城县| 柏乡县| 陇川县| 潍坊市| 根河市| 天峨县| 石楼县| 花垣县| 栾城县| 舒城县| 富平县| 涿鹿县| 高安市| 广元市| 台湾省| 繁峙县| 巨野县| 韶山市| 雷州市| 谷城县|