如何根据 Java 中的 URLConnection 针对 BufferedReader 设置超时?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/93357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I set a timeout against a BufferedReader based upon a URLConnection in Java?
提问by dacracot
I want to read the contents of a URL but don't want to "hang" if the URL is unresponsive. I've created a BufferedReader using the URL...
我想读取 URL 的内容,但如果 URL 没有响应,我不想“挂起”。我已经使用 URL 创建了一个 BufferedReader ...
URL theURL = new URL(url);
URLConnection urlConn = theURL.openConnection();
urlConn.setDoOutput(true);
BufferedReader urlReader = new BufferedReader(newInputStreamReader(urlConn.getInputStream()));
...and then begun the loop to read the contents...
...然后开始循环读取内容...
do
{
buf = urlReader.readLine();
if (buf != null)
{
resultBuffer.append(buf);
resultBuffer.append("\n");
}
}
while (buf != null);
...but if the read hangs then the application hangs.
...但如果读取挂起,则应用程序挂起。
Is there a way, without grinding the code down to the socket level, to "time out" the read if necessary?
有没有办法在不将代码研磨到套接字级别的情况下,在必要时“超时”读取?
回答by jsight
I think URLConnection.setReadTimeout is what you are looking for.
我认为 URLConnection.setReadTimeout 就是你要找的。
回答by Javaxpert
If you have java 1.4:
如果您有 Java 1.4:
I assume the connection timeout (URLConnection.setConnectTimeout(int timeout)) is of no use because you are doing some kind of streaming.
我认为连接超时 ( URLConnection.setConnectTimeout(int timeout)) 没有用,因为您正在执行某种流式传输。
---Do not kill the thread--- It may cause unknown problems, open descriptors, etc.
---不要杀死线程--- 可能会导致未知问题,打开描述符等。
Spawn a java.util.TimerTask where you will check if you have finished the process, otherwise, close the BufferedReader and the OutputStream of the URLConnection
生成一个 java.util.TimerTask,您将在其中检查您是否已完成该过程,否则,关闭 BufferedReader 和 URLConnection 的 OutputStream
Insert a boolean flag isFinishedand set it to true at the end of your loop and to false before the loop
插入一个布尔标志isFinished并在循环结束时将其设置为 true 并在循环前将其设置为 false
TimerTask ft = new TimerTask(){
public void run(){
if (!isFinished){
urlConn.getInputStream().close();
urlConn.getOutputStream().close();
}
}
};
(new Timer()).schedule(ft, timeout);
This will probably cause an ioexception, so you have to catch it. The exception is not a bad thing in itself. I'm omitting some declarations (i.e. finals) so the anonymous class can access your variables. If not, then create a POJO that maintains a reference and pass that to the timertask
这可能会导致 ioexception,因此您必须捕获它。例外本身并不是一件坏事。我省略了一些声明(即 finals),以便匿名类可以访问您的变量。如果没有,则创建一个维护引用的 POJO 并将其传递给 timertask
回答by Peter
Since Java 1.5, it is possible to set the read timeout in milliseconds on the underlying socket via the 'setReadTimeout(int timeout)' method on the URLConnection class.
从 Java 1.5 开始,可以通过 URLConnection 类上的“setReadTimeout(int timeout)”方法在底层套接字上设置以毫秒为单位的读取超时。
Note that there is also the 'setConnectTimeout(int timeout)' which will do the same thing for the initial connection to the remote server, so it is important to set that as well.
请注意,还有“setConnectTimeout(int timeout)”,它对与远程服务器的初始连接执行相同的操作,因此设置它也很重要。
回答by Chris Markle
I have been working on this issue in a JVM 1.4 environment just recently. The stock answer is to use the system properties sun.net.client.defaultReadTimeout (read timeout) and/or sun.net.client.defaultConnectTimeout. These are documented at Networking Propertiesand can be set via the -D argument on the Java command line or via a System.setProperty method call.
我最近一直在 JVM 1.4 环境中处理这个问题。常见的答案是使用系统属性 sun.net.client.defaultReadTimeout(读取超时)和/或 sun.net.client.defaultConnectTimeout。这些记录在网络属性中,可以通过 Java 命令行上的 -D 参数或通过 System.setProperty 方法调用进行设置。
Supposedly these are cached by the implementation so you can't change them from one thing to another so one they are used once, the values are retained.
据说这些是由实现缓存的,因此您无法将它们从一件事更改为另一件事,因此它们只使用一次,值将保留。
Also they don't really work for SSL connections ala HttpsURLConnection. There are other ways to deal with that using a custom SSLSocketFactory.
此外,它们实际上不适用于 SSL 连接 ala HttpsURLConnection。还有其他方法可以使用自定义 SSLSocketFactory 来处理。
Again, all this applies to JVM 1.4.x. At 1.5 and above you have more methods available to you in the API (as noted by the other responders above).
同样,所有这些都适用于 JVM 1.4.x。在 1.5 及更高版本中,您可以在 API 中使用更多方法(如上述其他响应者所述)。
回答by phychem
For Java 1.4, you may use SimpleHttpConnectionManager.getConnectionWithTimeout(hostConf,CONNECTION_TIMEOUT) from Apache
对于 Java 1.4,您可以使用 Apache 的 SimpleHttpConnectionManager.getConnectionWithTimeout(hostConf,CONNECTION_TIMEOUT)

