Я хочу прочитать содержимое 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);
... но если чтение зависает, значит зависает приложение.
Есть ли способ, не доводя код до уровня сокета, при необходимости "тайм-аут" чтения?




Я думаю, что URLConnection.setReadTimeout - это то, что вы ищете.
Начиная с Java 1.5, можно установить тайм-аут чтения в миллисекундах для базового сокета с помощью метода setReadTimeout (int timeout) в классе URLConnection.
Обратите внимание, что есть также setConnectTimeout (int timeout), который будет делать то же самое для начального подключения к удаленному серверу, поэтому важно установить и его.
Если у вас 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, который поддерживает ссылку, и передайте ее в timertask.
Это хорошее решение, но я думаю, что ваша задача сработает только один раз. Это, вероятно, не удастся для долгосрочного процесса передачи, поэтому было бы лучше запустить с интервалом и остановить таймер, когда это будет сделано. Хотя идея интересная.
Я недавно работал над этой проблемой в среде 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 (как отметили другие респонденты выше).
Для Java 1.4 вы можете использовать SimpleHttpConnectionManager.getConnectionWithTimeout (hostConf, CONNECTION_TIMEOUT) из Apache
Не openConnection () запускает соединение, поэтому установка тайм-аута открытого соединения будет иметь эффект, или он считывает значение даже после того, как запустил процесс соединения?