【问题标题】:How to set a timeout while reading from InputStream using httpurlconnection?使用 httpurlconnection 从 InputStream 读取时如何设置超时?
【发布时间】:2016-01-02 03:05:36
【问题描述】:

我有一个 java 应用程序,我在其中使用 HttpURLConnection 下载文件。我将连接超时设置为 15 秒,将读取超时属性设置为 1 小时。根据我的理解,如果服务器上的文件大到需要超过 1 小时才能下载,它将失败并出现超时异常。工作正常。问题是,当我在下载过程中(从 InputStream 读取缓冲区)拔出 Internet 电缆时,下载过程不会立即终止,需要 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();
    }
}

【问题讨论】:

    标签: java timeout httpurlconnection


    【解决方案1】:

    据我了解,如果服务器上的文件大到需要 1 个多小时才能下载,它将失败并出现超时异常。

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

    工作正常。

    工作正常,但不像你描述的那样。

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

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

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

    设置更短的超时时间。将其设置得足够长,以便服务器应在该时间间隔内响应,并且足够短的电缆拉动不会花费太长时间来超时。一个小时太长了。尝试几分钟。

    【讨论】:

    • 感谢 EJP 纠正我,您正确解释了为什么需要一个小时。我将尝试 1 分钟,因为我的带宽非常高,并且我使用 Amazon S3 云作为服务器,所以我希望这足以发出读取请求。
    • @Dev_Vikram 超时时间与带宽几乎没有关系。它与路径延迟有关,但与服务器的预期服务时间以及您准备等待多长时间有关。我想说一分钟有点太短了。
    • 是的。我将使用 15 分钟,这是 .NET 中的默认设置。再次感谢您的及时回复。 :)
    • 现在太长了,我在上面说“几分钟”,这就是我的意思:两三个。 only information I could quickly find about .NET read timeouts 说是 100 秒。我很难相信这是 15 分钟。
    • 在不同的网络速度和不同的客户端上测试。在我看来,2 分钟最适合我的需要。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-02-17
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    相关资源
    最近更新 更多