11

我想阅读 URL 的内容,但不想在 URL 无响应时“挂起”。我使用 URL 创建了一个 BufferedReader ...

URL theURL = new URL(url);
URLConnection urlConn = theURL.openConnection();
urlConn.setDoOutput(true);
BufferedReader urlReader = new BufferedReader(newInputStreamReader(urlConn.getInputStream()));

...然后开始循环读取内容...

do
    {
    buf = urlReader.readLine();
    if (buf != null)
        {
        resultBuffer.append(buf);
        resultBuffer.append("\n");
        }
    }
while (buf != null);

...但是如果读取挂起,则应用程序挂起。

有没有办法在不将代码磨到套接字级别的情况下,在必要时“超时”读取?

4

5 回答 5

13

我认为 URLConnection.setReadTimeout 是您正在寻找的。

于 2008-09-18T15:08:51.147 回答
3

如果你有 java 1.4:

我认为连接超时 ( URLConnection.setConnectTimeout(int timeout)) 没有用,因为您正在执行某种流式传输。

---不要杀死线程--- 可能会导致未知问题,打开描述符等。

生成一个 java.util.TimerTask,您将在其中检查是否已完成该过程,否则,关闭 BufferedReader 和 URLConnection 的 OutputStream

插入一个布尔标志isFinished并在循环结束时将其设置为 true 并在循环之前将其设置为 false

TimerTask ft = new TimerTask(){
   public void run(){
     if (!isFinished){
       urlConn.getInputStream().close();
      urlConn.getOutputStream().close();
     }
   }
};

(new Timer()).schedule(ft, timeout);

这可能会导致 ioexception,所以你必须抓住它。例外本身并不是一件坏事。我省略了一些声明(即finals),因此匿名类可以访问您的变量。如果没有,则创建一个维护引用并将其传递给 timertask 的 POJO

于 2008-09-18T15:28:58.290 回答
2

从 Java 1.5 开始,可以通过 URLConnection 类上的 'setReadTimeout(int timeout)' 方法在底层套接字上设置读取超时(以毫秒为单位)。

请注意,还有 'setConnectTimeout(int timeout)' 将对与远程服务器的初始连接执行相同的操作,因此设置它也很重要。

于 2008-09-18T15:12:22.557 回答
1

我最近一直在 JVM 1.4 环境中处理这个问题。常用的答案是使用系统属性 sun.net.client.defaultReadTimeout(读取超时)和/或 sun.net.client.defaultConnectTimeout。这些记录在Networking Properties中,可以通过 Java 命令行上的 -D 参数或通过 System.setProperty 方法调用进行设置。

假设这些是由实现缓存的,因此您不能将它们从一件事更改为另一件事,因此它们被使用一次,值将被保留。

它们也不适用于 SSL 连接 ala HttpsURLConnection。还有其他方法可以使用自定义 SSLSocketFactory 来处理。

同样,所有这些都适用于 JVM 1.4.x。在 1.5 及更高版本中,您可以在 API 中使用更多方法(如上述其他响应者所述)。

于 2008-09-30T22:19:16.000 回答
1

对于 Java 1.4,您可以使用 Apache 的 SimpleHttpConnectionManager.getConnectionWithTimeout(hostConf,CONNECTION_TIMEOUT)

于 2012-11-26T06:52:22.697 回答