Comment définir un délai d'attente par rapport à un BufferedReader basé sur une connexion URLConnection en Java?
Question
Je souhaite lire le contenu d'une URL, mais je ne souhaite pas "bloquer". si l'URL ne répond pas. J'ai créé un BufferedReader à l'aide de l'URL ...
URL theURL = new URL(url);
URLConnection urlConn = theURL.openConnection();
urlConn.setDoOutput(true);
BufferedReader urlReader = new BufferedReader(newInputStreamReader(urlConn.getInputStream()));
... et ensuite commencé la boucle pour lire le contenu ...
do
{
buf = urlReader.readLine();
if (buf != null)
{
resultBuffer.append(buf);
resultBuffer.append("\n");
}
}
while (buf != null);
... mais si la lecture se bloque, l'application se bloque.
Existe-t-il un moyen, sans rédiger le code jusqu'au niveau du socket, de "time out"? la lecture si nécessaire?
La solution
Je pense que URLConnection.setReadTimeout est ce que vous recherchez.
Autres conseils
Si vous avez Java 1.4:
Je suppose que le délai de connexion ( URLConnection.setConnectTimeout (int délai)
) n’est d'aucune utilité, car vous effectuez une sorte de diffusion en continu.
--- Ne tuez pas le fil : des problèmes inconnus, des descripteurs ouverts, etc. peuvent en résulter.
Créez une tâche java.util.TimerTask où vous pourrez vérifier si vous avez terminé le processus. Sinon, fermez BufferedReader et le flux de sortie de l'URLConnection
Insérez un indicateur booléen isFinished
et définissez-le sur true à la fin de votre boucle et sur false avant la boucle
TimerTask ft = new TimerTask(){
public void run(){
if (!isFinished){
urlConn.getInputStream().close();
urlConn.getOutputStream().close();
}
}
};
(new Timer()).schedule(ft, timeout);
Cela provoquera probablement une ioexception, vous devez donc l’attraper. L'exception n'est pas une mauvaise chose en soi. J'omets certaines déclarations (finales) pour que la classe anonyme puisse accéder à vos variables. Si ce n'est pas le cas, créez un POJO qui conserve une référence et transmettez-le au timertask
Depuis Java 1.5, il est possible de définir le délai de lecture en millisecondes sur le socket sous-jacent via la méthode 'setReadTimeout (int timeout)' sur la classe URLConnection.
Notez qu'il existe également le 'setConnectTimeout (int timeout)' qui fera la même chose pour la connexion initiale au serveur distant. Il est donc important de le définir également.
Je travaille sur ce problème dans un environnement JVM 1.4 tout récemment. La réponse courante consiste à utiliser les propriétés système sun.net.client.defaultReadTimeout (délai de lecture) et / ou sun.net.client.defaultConnectTimeout. Celles-ci sont documentées dans les Propriétés de mise en réseau et peuvent être défini via l'argument -D sur la ligne de commande Java ou via un appel à la méthode System.setProperty.
Celles-ci sont supposées être mises en cache par la mise en œuvre, vous ne pouvez donc pas les changer, alors elles sont utilisées une fois. Les valeurs sont conservées.
En outre, ils ne fonctionnent pas vraiment pour les connexions SSL à la manière de HttpsURLConnection. Il existe d'autres moyens de gérer cela à l'aide d'un SSLSocketFactory personnalisé.
Encore une fois, tout cela s’applique à JVM 1.4.x. À partir de 1.5, vous avez plus de méthodes à votre disposition dans l'API (comme noté par les autres répondants ci-dessus).
Pour Java 1.4, vous pouvez utiliser SimpleHttpConnectionManager.getConnectionWithTimeout (hostConf, CONNECTION_TIMEOUT) d'Apache