2015-10-05 171 views
3

我有一個Java應用程序,我使用HttpURLConnection下載文件。我在連接超時中設置了15秒,在讀取超時屬性中設置了1小時。根據我的理解,如果服務器上的文件足夠大,需要花費1個多小時才能下載,它將以超時異常失敗。工作正常。問題是,在下載過程中(從InputStream讀取緩衝區)從客戶機拔出Internet電纜時,下載過程不會立即終止,需要1小時(讀取超時)來中斷下載。有什麼辦法可以終止下載過程嗎? 以下是源代碼:如何使用httpurlconnection從InputStream讀取時設置超時?

public class HttpDownloadUtility { 
private static final int BUFFER_SIZE = 4096; 
public static void downloadFile(String fileURL, String saveDir) 
      throws IOException { 
     URL url = new URL(fileURL); 
     HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); 
     httpConn.setConnectTimeout(15*1000); 
     httpConn.setReadTimeout(60*60*1000); 
     int responseCode = httpConn.getResponseCode(); 

     // always check HTTP response code first 
     if (responseCode == HttpURLConnection.HTTP_OK) { 
      String fileName = ""; 
      String disposition = httpConn.getHeaderField("Content-Disposition"); 
      String contentType = httpConn.getContentType(); 
      int contentLength = httpConn.getContentLength(); 

      if (disposition != null) { 
       // extracts file name from header field 
       int index = disposition.indexOf("filename="); 
       if (index > 0) { 
        fileName = disposition.substring(index + 10, 
          disposition.length() - 1); 
       } 
      } else { 
       // extracts file name from URL 
       fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1, 
         fileURL.length()); 
      } 

      System.out.println("Content-Type = " + contentType); 
      System.out.println("Content-Disposition = " + disposition); 
      System.out.println("Content-Length = " + contentLength); 
      System.out.println("fileName = " + fileName); 

      // opens input stream from the HTTP connection 
      InputStream inputStream = httpConn.getInputStream(); 
      String saveFilePath = saveDir + File.separator + fileName; 

      // opens an output stream to save into file 
      FileOutputStream outputStream = new FileOutputStream(saveFilePath); 

      int bytesRead = -1; 
      byte[] buffer = new byte[BUFFER_SIZE]; 
      while ((bytesRead = inputStream.read(buffer)) != -1) { //This is where the download gets stuck on some connection issues 
       outputStream.write(buffer, 0, bytesRead); 
      } 

      outputStream.close(); 
      inputStream.close(); 

      System.out.println("File downloaded"); 
     } else { 
      System.out.println("No file to download. Server replied HTTP code: " + responseCode); 
     } 
     httpConn.disconnect(); 
    } 
} 

回答

1

按我的理解,如果在服務器上的文件是大到足以需要1個多小時的下載,它將失敗,超時異常。

否。如果服務器無法響應任何單個讀取請求超過一個小時,它將失敗。當您撥打read()時,超時開始,並在收到對該讀取的響應或超時期限到期時結束。然後再次開始下一次閱讀。總時間與它無關。你完全誤解了。

工作正常。

工作正常,但不像您所描述的那樣。

問題是,當我在下載過程中(從InputStream讀取緩衝區)從客戶端機器拉出Internet電纜時,下載過程不會立即終止,需要1小時(讀取超時)打破下載。

這正是它應該做的,如上所述。

有沒有什麼辦法可以終止下載過程?

設置較短的超時時間。設置足夠長的時間,以便服務器在該時間間隔內做出響應,並且足夠短的電纜拉力不會花太長時間才能超時。一小時太長了。嘗試幾分鐘。

+0

謝謝EJP糾正我,你正確解釋了爲什麼需要一個小時。我將在1分鐘內嘗試一下,因爲我擁有相當高的帶寬,並且我使用Amazon S3雲作爲服務器,所以我希望這足以滿足讀取請求的要求。 –

+0

@Dev_Vikram超時時間與帶寬很少或沒有關係。它與路徑*延遲*有關,但它與服務器的預期服務時間以及您準備等待的時間有關。我會說一分鐘太短了。 – EJP

+0

是的。我打算用15分鐘,這在.NET中是默認的。再次感謝您的及時答覆。 :) –