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

我有一个
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();
    }
}

最佳答案

As per my understanding, if file on server is big enough to take more than 1 hour to download, it will fail with timeout exception.

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

Works fine.

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

The problem is, when I pull the Internet cable out from the client machine while download is in progress(reading buffer from InputStream), the download process does not terminates immediately, it takes 1 hour (read timeout) to break the download.

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

Is there any way I can terminate the download process?

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

点赞