Как я могу установить тайм-аут против BufferedReader на основе URLConnection в Java? - PullRequest
10 голосов
/ 18 сентября 2008

Я хочу прочитать содержимое URL, но не хочу «висеть», если URL не отвечает. Я создал BufferedReader, используя URL ...

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);

... но если чтение зависает, приложение зависает.

Есть ли способ, без перемалывания кода до уровня сокета, при необходимости "тайм-аут" читать?

Ответы [ 5 ]

12 голосов
/ 18 сентября 2008

Я думаю, что URLConnection.setReadTimeout это то, что вы ищете.

3 голосов
/ 18 сентября 2008

Если у вас есть Java 1.4:

Я предполагаю, что тайм-аут соединения (URLConnection.setConnectTimeout(int timeout)) бесполезен, потому что вы выполняете потоковую передачу.

--- Не уничтожать поток --- Это может вызвать неизвестные проблемы, открыть дескрипторы и т. Д.

Создать java.util.TimerTask, где вы будете проверять, закончили ли вы процесс, в противном случае закройте BufferedReader и OutputStream URLConnection

Вставьте логический флаг isFinished и установите для него значение true в конце цикла и значение false перед циклом

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

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

Это, вероятно, вызовет исключение ioexception, поэтому вы должны его поймать. Исключение само по себе неплохое. Я опускаю некоторые объявления (то есть финалы), чтобы анонимный класс мог получить доступ к вашим переменным. Если нет, то создайте POJO, который поддерживает ссылку, и передайте ее таймерной задаче

2 голосов
/ 18 сентября 2008

Начиная с Java 1.5, можно установить тайм-аут чтения в миллисекундах на базовом сокете с помощью метода setReadTimeout (int timeout) класса URLConnection.

Обратите внимание, что есть также setConnectTimeout (int timeout), который будет делать то же самое для первоначального подключения к удаленному серверу, поэтому важно также установить это.

1 голос
/ 26 ноября 2012

Для Java 1.4 вы можете использовать SimpleHttpConnectionManager.getConnectionWithTimeout (hostConf, CONNECTION_TIMEOUT) из Apache

1 голос
/ 01 октября 2008

Я работал над этой проблемой в среде JVM 1.4 совсем недавно. Основной ответ заключается в использовании системных свойств sun.net.client.defaultReadTimeout (тайм-аут чтения) и / или sun.net.client.defaultConnectTimeout. Они задокументированы в Сетевые свойства и могут быть установлены через аргумент -D в командной строке Java или через вызов метода System.setProperty.

Предположительно, они кэшируются реализацией, поэтому вы не можете изменить их с одного на другое, поэтому, когда они используются один раз, значения сохраняются.

Также они не работают для соединений SSL, как HttpsURLConnection. Есть и другие способы справиться с этим, используя пользовательский SSLSocketFactory.

Опять же, все это относится к JVM 1.4.x. На уровне 1.5 и выше у вас есть больше методов, доступных вам в API (как отмечалось другими респондентами выше).

...