2015-10-05 169 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中是默认的。再次感谢您的及时答复。 :) –