Comment définir un délai d'attente par rapport à un BufferedReader basé sur une connexion URLConnection en Java?

StackOverflow https://stackoverflow.com/questions/93357

  •  01-07-2019
  •  | 
  •  

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?

Était-ce utile?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top