熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

用Java制作網絡文件下載系統

2013-11-23 19:13:45  來源: Java核心技術 

  由於Linux操作系統的興起和Java語言的日漸成熟使用Java語言實現一個跨平台的外觀一致的下載工具軟件已成為可能網絡螞蟻是大家非常熟知的下載工具軟件我采用Java語言實現了類似網絡螞蟻的基本功能的軟件Jants本文介紹了一些技術實現要點
  
  單線程直接獲取網絡文件
  
  單線程直接獲取網絡文件的關鍵點是獲取網絡文件以確定基本方法的正確性它的初始代碼的內容比較簡單可以利用HTTP的基本知識進行設計它的基本原理是連接網絡地址打開連接並獲取輸入流從輸入流中讀取數據實現代碼(測試過程中使用的)如下
  
  int data;//從輸入流中獲取數據
  URL url=new URL();
  //創建連接的地址
  HttpURLConnection connection=urlopenConnection();
  //打開連接
  int responsCode=connection getResponseCode();
  //返回Http的響應狀態碼
  InputStream input=connectiongetInputStream();
  //獲取輸入流
  Systemoutprintln(responseCode:+responseCode);
  While((data=inputread())!=)
  Systemoutprintln(data);
  //將獲取的數據打到屏幕顯示出來
  
  
  
  
  單線程斷點續傳
  
  
  大家常常有這樣的體會:下載一個幾十兆的文件時突然斷線結果前功盡棄可以使用斷點續傳解決這個問題
  
  基本原理
  
  這裡主要介紹一下斷點續傳的原理斷點續傳的原理很簡單只是在HTTP請求上和一般的下載有所不同
  
  所謂斷點續傳也就是要從文件已經下載的地方開始繼續下載所以在客戶端傳給Web服務器的時候要多加一條信息——下載的起始位置且服務器返回的HTTP狀態代碼也從轉變為
  
  上述要點可以使用Java語言中的HttpURLConnection類中的setRequestProperty()方法來設置
  
  斷點續傳的關鍵步驟
  
  實現提交斷點續傳下載的起始位置
  
  Java的Net包中提供了這種功能代碼如下
  
  URL url = new URL(;);
  HttpURLConnection httpConnection=(HttpURLConnection) urlopenConnection();
  //設置斷點續傳的開始位置
  (RANGEbytes=);
  //設置請求信息
  (GET/downzip HTTP/);
  //設置接受信息
  (Acceptimage/gifimage/xxbitmapapplication/
  msword*/*);
  //設置連接信息
  (ConnectionKeepAlive);
  //獲得輸入流
  InputStream input = ();
  
  從輸入流中取出的字節流就是downzip文件從字節開始的字節流
  
  保存獲得的字節流到文件中
  
  由於文件的下載涉及到斷點續傳因此在保存文件的時候需要對文件進行隨機讀寫特別是在多線程下載的過程中需要在寫文件之前在文件中定位
  
  在Java的IO包中的RandomAccessFile類可以滿足這種設計需求該類在文件中定位指針時用到的方法是seek(Long)
  
  操作相當簡單假設從字節處開始保存文件代碼如下
  
  RandomAccess oSavedFile = new RandomAccessFile(downziprw);
  //創建隨機文件
  long nPos = ;
  //定位文件指針到nPos位置
  oSavedFileseek(nPos);
  byte[] b = new byte[];
  int nRead;
  //從輸入流中讀入字節流然後寫到文件中
  while((nRead=inputread(b)) > )
  { //input為網絡輸入流
   oSavedFilewrite(bnRead);
  }
  
  保存已經下載的文件的長度值
  
  由於在每次斷開連接時都要保存已下載文件的長度且應進行永久保存因此將它保存到文件介質中這裡采用的是對象序列化的方法——將要保存的內容序列化到一個臨時文件中代碼如下
  
  long nStart;
  //記錄已經下載的字節數
  File tempFile=new File(donwziptmp);
  //創建臨時文件
  FileOutputStream file=new FileOutputStream(tempFile);
  //創建文件輸出流
   ObjectOutputStream serialize=new ObjectOutputStream(file)
  //創建文件序列化流
  serializewriteObject(nStart);//序列化
  serializeflush();
  //刷新序列化流
  fileclose();
  //關閉文件輸出流
  serializeclose();
  //關閉序列化流
  
  
  
  
  多線程的斷點續傳
  
  
  加入斷點續傳以後下載速度還沒能得到提高為防止已下載文件數據的丟失也為提高網絡文件的下載速度可在其中加入多線程雖然前兩步已經基本實現似乎再加入多線程時應該比較容易但是並非如此在多線程的編程過程中需要考慮到線程的同步與互斥由於是多線程進行斷點續傳還要考慮記錄多個斷點位置且記錄斷點位置時也要考慮同步互斥等問題所有這些都使得這一步比較復雜
  
  同步的考慮
  
  同步的基本思想是避免多個線程訪問同一個資源時出現問題由於多線程對同一個文件資源進行讀寫因此為了避免出現錯誤要進行讀寫控制——即同步Java中使用synchronized實現線程之間的同步Java是面向對象的語言它的資源是以對象的形式表現的因此Java同步機制的作用就是力圖避免對對象的訪問沖突
  
  對需要同步的方法或代碼段進行標記以實現同步需要用到關鍵字synchronized系統使用synchronized關鍵字聲明的方法就是為其設置特殊的標記這個標記起著信號量的作用每當調用該方法時Java的運行系統都將進行檢查以確認此標記的狀態看相應的代碼是否已經被調用執行如沒有執行系統將把這個內部標記授予調用代碼的線程方法運行結束後標記被釋放在標記被釋放之前任何其它的對象不得調用此方法
  
  主要的同步代碼如下(在下載數據保存入文件中時使用)
  
  public synchronized int write(byte[] bint nStartint len){
   int n=;
   try{
   rfwrite(bnStartlen);
  //調用另一個類的方法向文件中寫入數據
   n=len;
   }catch(IOException ioe){
   ioeprintStackTrace();
   }
   return n;
   }
  
  在保存已下載的字節數時由於多個斷點位置在不同的線程中記錄所以必須在所有線程都結束時才能保存為此解決的辦法是再開出一個線程用以持續監測是否所有的線程都已經結束若結束保存所有的斷點位置否則繼續監測同樣在文件下載的線程中需要設置標志位以記錄線程是否結束基本代碼如下(在監測線程中使用)
  
  stop=false;
  while(!stop){
     if(UtilitybStop[] && UtilitybStop[] && UtilitybStop[] && UtilitybStop[] && UtilitybStop[]){
      Systemoutprintln(Serialize);
      UtilityserializeOut();
      //調用序列化函數以保存斷點位置於文件中
      javaantssetStopFalse();
      javaantssetStartTrue();
      stop=true;
      }
  
  
  
  斷點數據的記錄
  
  筆者使用的是一個靜態數組以記錄斷點位置由於有多個斷點位置可采用一個函數進行統一保存
  
  public static void serializeOut(){
    try{
     File tempFile=new File(getTempFileName()++tmp);
       FileOutputStream file=new FileOutputStream(tempFile);
      ObjectOutputStream serialize=new ObjectOutputStream(file);
     for(int i=;i<;i++){
      serializewriteObject(StringvalueOf(nStart[i]));
      serializewriteObject(StringvalueOf(nStop[i]));
     }
     serializeflush();
     fileclose();
     serializeclose();
   }catch(Exception e){
       Systemoutprintln(etoString());
    }
  }
  
  圖形界面
  
  該文件下載系統的圖形界面與流行下載軟件——網絡螞蟻很相似圖形界面的實現使用了Swing包限於篇幅這裡不再贅述Jants的圖形界面如圖和圖所示
   
  圖 Jants主界面
  
  圖 Jants下載過程中的界面
  
  發布
  
  使用jar命令將所有的文件下載系統的class文件打包為javaantsjar文件並在其中加入Menifestmf文件指定MainClass
  
  打包代碼 jar cfv ** javaantsjar
  運行代碼javaw classpath javaantsjar Main
  
  

From:http://tw.wingwit.com/Article/program/Java/hx/201311/26485.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.