Come posso impostare un timeout rispetto a BufferedReader basato su URLConnection in Java?

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

  •  01-07-2019
  •  | 
  •  

Domanda

Desidero leggere il contenuto di un URL ma non voglio "bloccarmi" se l'URL non risponde.Ho creato un BufferedReader utilizzando l'URL...

URL theURL = new URL(url);
URLConnection urlConn = theURL.openConnection();
urlConn.setDoOutput(true);
BufferedReader urlReader = new BufferedReader(newInputStreamReader(urlConn.getInputStream()));

...e poi ho iniziato il ciclo per leggere il contenuto...

do
    {
    buf = urlReader.readLine();
    if (buf != null)
        {
        resultBuffer.append(buf);
        resultBuffer.append("\n");
        }
    }
while (buf != null);

...ma se la lettura si blocca, anche l'applicazione si blocca.

Esiste un modo, senza ridurre il codice a livello di socket, per "timeout" la lettura, se necessario?

È stato utile?

Soluzione

Penso che URLConnection.setReadTimeout sia quello che stai cercando.

Altri suggerimenti

Se hai Java 1.4:

Presumo che il timeout della connessione (URLConnection.setConnectTimeout(int timeout) ) è inutile perché stai eseguendo una sorta di streaming.

---Non uccidere il thread--- Potrebbe causare problemi sconosciuti, descrittori aperti, ecc.

Genera un java.util.TimerTask dove controllerai se hai finito il processo, altrimenti chiudi BufferedReader e OutputStream di URLConnection

Inserisci un flag booleano isFinished e impostalo su true alla fine del ciclo e su false prima del ciclo

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

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

Ciò probabilmente causerà un'eccezione io, quindi devi catturarla.L’eccezione non è di per sé una cosa negativa.Sto omettendo alcune dichiarazioni (es.finals) in modo che la classe anonima possa accedere alle tue variabili.In caso contrario, crea un POJO che mantenga un riferimento e passalo al timertask

A partire da Java 1.5, è possibile impostare il timeout di lettura in millisecondi sul socket sottostante tramite il metodo 'setReadTimeout(int timeout)' nella classe URLConnection.

Tieni presente che esiste anche 'setConnectTimeout(int timeout)' che farà la stessa cosa per la connessione iniziale al server remoto, quindi è importante impostare anche quello.

Ho lavorato su questo problema in un ambiente JVM 1.4 proprio di recente.La risposta standard è utilizzare le proprietà di sistema sun.net.client.defaultReadTimeout (timeout di lettura) e/o sun.net.client.defaultConnectTimeout.Questi sono documentati in Proprietà di rete e può essere impostato tramite l'argomento -D sulla riga di comando Java o tramite una chiamata al metodo System.setProperty.

Presumibilmente questi vengono memorizzati nella cache dall'implementazione, quindi non è possibile modificarli da una cosa all'altra, quindi una volta utilizzati una volta, i valori vengono mantenuti.

Inoltre non funzionano realmente per le connessioni SSL come HttpsURLConnection.Esistono altri modi per gestire ciò utilizzando un SSLSocketFactory personalizzato.

Ancora una volta, tutto ciò si applica a JVM 1.4.x.A partire dalla versione 1.5 hai a disposizione più metodi nell'API (come notato dagli altri risponditori sopra).

Per Java 1.4, puoi utilizzare SimpleHttpConnectionManager.getConnectionWithTimeout(hostConf,CONNECTION_TIMEOUT) da Apache

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top