2010-08-05 125 views
21

我試圖從我的Yahoo!下載一個大文件。網站服務器顯然是設置(不是由我)斷開下載,如果他們沒有在100秒內完成。該文件足夠小,通常可以成功傳輸。在數據速率較慢且下載斷開的情況下,是否有辦法在發生斷開連接的文件偏移量處恢復URLConnection?下面的代碼:如何恢復中斷的下載

// Setup connection. 
URL url = new URL(strUrl[0]); 
URLConnection cx = url.openConnection(); 
cx.connect(); 

// Setup streams and buffers. 
int lengthFile = cx.getContentLength(); 
InputStream input = new BufferedInputStream(url.openStream()); 
OutputStream output = new FileOutputStream(strUrl[1]); 
byte data[] = new byte[1024]; 

// Download file. 
for (total=0; (count=input.read(data, 0, 1024)) != -1; total+=count) { 
    publishProgress((int)(total*100/lengthFile)); 
    output.write(data, 0, count); 
    Log.d("AsyncDownloadFile", "bytes: " + total); 
} 

// Close streams. 
output.flush(); 
output.close(); 
input.close(); 
+1

也許使用非雅虎網站服務器以外的東西:) Android沒有'scp'功能嗎?這裏的大圖是什麼? – 2010-08-05 03:16:09

回答

29

嘗試使用「範圍」請求頭:

// Open connection to URL. 
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 

// Specify what portion of file to download. 
connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); 
// here "downloaded" is the data length already previously downloaded. 

// Connect to server. 
connection.connect(); 

已經這樣做了,你可以seek在給定的點(只是你的下載數據的長度面前,說X )並開始在那裏寫入新下載的數據。請務必爲範圍標題使用相同的值X。約14.35.2 Range Retrieval Requests

更多細節及源代碼

詳細信息,可以發現here

+3

不錯的例子,你應該檢查服務器的響應代碼是206「Partial Content」,以確保它支持字節範圍請求。 – 2010-08-05 09:08:27

+1

奈克斯,感謝您的幫助。我仍然在閱讀w3文檔,希望找到雅虎的原因。服務器似乎總是從文件的開頭傳輸而不是從指定範圍的開始傳輸。在這個問題的part 2中描述了進一步的嘗試。 – gregS 2010-08-07 15:58:35

+0

我收到了Yahoo!的回覆。技術支持說雅虎!服務器不支持字節範圍請求: 「由於我們使用服務器池並且每個請求可能到達不同服務器,因此Yahoo!虛擬主機不支持Accept-range標頭,並且您會在響應頭中看到connection = [close]表明這一點。「 – gregS 2010-08-11 11:11:57

0

這裏,你可以用一個例子代碼:

import java.io.*; 
import java.net.*; 


public class HttpUrlDownload { 

    public static void main(String[] args) { 
     String strUrl = "http://VRSDLSCEN001:80//DLS//lib//clics.jar"; 
     String DESTINATION_PATH = "clics.jar"; 

     int count = 0; 
     while (true) { 
      count++; 
      if (download(strUrl, DESTINATION_PATH) == true || count > 20) { 
      break; 
      }   
     } 
    } 

    public static boolean download(String strUrl, String DESTINATION_PATH) { 
     BufferedInputStream in = null; 
     FileOutputStream fos = null; 
     BufferedOutputStream bout = null; 
     URLConnection connection = null; 

     int downloaded = 0; 

     try { 
      System.out.println("mark ... download start"); 
      URL url = new URL(strUrl); 

      connection = url.openConnection(); 

      File file=new File(DESTINATION_PATH); 
      if(file.exists()){ 
       downloaded = (int) file.length(); 
      } 
      if (downloaded == 0) { 
       connection.connect(); 
      } 
      else { 
       connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); 
       connection.connect(); 
      } 

      try { 
       in = new BufferedInputStream(connection.getInputStream()); 
      } catch (IOException e) { 
       int responseCode = 0; 
       try { 
        responseCode = ((HttpURLConnection)connection).getResponseCode(); 
       } catch (IOException e1) { 
       e1.printStackTrace(); 
       } 

       if (responseCode == 416) {   
        return true; 
       } else { 
        e.printStackTrace(); 
        return false; 
       } 
      } 

      fos=(downloaded==0)? new FileOutputStream(DESTINATION_PATH): new FileOutputStream(DESTINATION_PATH,true); 
      bout = new BufferedOutputStream(fos, 1024); 

      byte[] data = new byte[1024]; 
      int x = 0; 
      while ((x = in.read(data, 0, 1024)) >= 0) { 
       bout.write(data, 0, x); 
      } 

      in.close(); 
      bout.flush(); 
      bout.close(); 
      return false; 

     } catch (IOException e) { 
      e.printStackTrace(); 
      return false; 
     } finally { 
      if (in != null) { 
       try { 
        in.close(); 
       } catch (IOException e) { 
       } 
      } 
      if (fos != null) { 
       try { 
        fos.close(); 
       } catch (IOException e) { 
       } 
      } 
      if (bout != null) { 
       try { 
        bout.close(); 
       } catch (IOException e) { 
       } 
      } 

      if (connection != null) { 
       ((HttpURLConnection)connection).disconnect(); 
      } 
     } 
    } 
}