如何使用httpurlconnection从InputStream读取时设置超时?

时间:2015-10-05 12:42:12

标签: java timeout httpurlconnection

我有一个java应用程序,我在其中使用HttpURLConnection下载文件。我在连接超时中设置了15秒,在读取超时属性中设置了1小时。根据我的理解,如果服务器上的文件足够大,下载时间超过1小时,则会因超时异常而失败。工作良好。问题是,当我在下载过程中从客户端计算机拔出Internet电缆(从InputStream读取缓冲区)时,下载过程不会立即终止,需要1小时(读取超时)来中断下载。有什么办法可以终止下载过程吗? 以下是源代码:

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 个答案:

答案 0 :(得分:1)

  

根据我的理解,如果服务器上的文件足够大,下载时间超过1小时,则会因超时异常而失败。

没有。如果服务器在一个多小时内未能响应任何单个读取请求,则它将失败。当您调用read()时,超时开始,并在收到对该读取的响应或超时时间到期时结束。然后它再次开始下一次读取。总时间与它无关。你完全误解了。

  

工作正常。

工作正常但不如你所描述的那样。

  

问题是,当我在下载过程中从客户端计算机拔出Internet电缆(从InputStream读取缓冲区)时,下载过程不会立即终止,需要1小时(读取超时)才能打破下载

如上所述,这正是它应该做的事情。

  

有什么方法可以终止下载过程吗?

设置较短的超时时间。设置它足够长,以便服务器应该在该间隔内响应,并且足够短的电缆拉动不需要太长时间才能超时。一个小时太长了。试试几分钟。