2011-10-24 18 views
11
long end=System.currentTimeMillis()+60*10; 
    InputStreamReader fileInputStream=new InputStreamReader(System.in); 
    BufferedReader bufferedReader=new BufferedReader(fileInputStream); 
    try 
    { 
     while((System.currentTimeMillis()<end) && (bufferedReader.readLine()!=null)) 
     { 

     } 
     bufferedReader.close(); 
    } 
    catch(java.io.IOException e) 
    { 
     e.printStackTrace(); 
    } 

in realtà ho provato a fare quanto sopra per la lettura in 600 millisecondi di tempo dopo il quale non dovrebbe permettere la lettura, ma la readline del BufferedReader è aiuto blocking.Pleasecome leggere dallo standard input non-blocking?

+0

Suppongo che darai tempo all'utente di scrivere effettivamente qualcosa. ;) –

risposta

3

Si potrebbe verificare con BufferedReader.available()> 0 se ci sono caratteri da leggere.

String s; 

while((System.currentTimeMillis()<end)) 
{ 
    if (bufferedReader.available() > 0) 
     s += bufferedReader.readLine(); 
} 

bufferedReader.close(); 
+5

Non esiste un metodo chiamato in BufferedReader, ma siamo pronti, quindi ho provato con esso e l'ho fatto. Grazie sibbo. – pavi

+0

Ok, ho dimenticato, il metodo available() è implementato da InputStream;) – Sibbo

+5

ready() non garantisce che una linea sia pronta solo per la presenza di alcuni dati. readLine() potrebbe ancora bloccare. vedi http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#ready%28%29 –

0

BufferReader.readLine() può bloccare per lungo tempo se una linea è estremamente lunghi come caratteri 1M.

Il file contiene righe così lunghe?

Se sì, potrebbe essere necessario suddividere le linee o utilizzare metodi di lettura per-char come BufferReader.read().

+0

No, in realtà, leggevo solo una piccola quantità di dati ma entro un intervallo di tempo specifico. L'ho fatto attraverso il metodo pronto. Grazie per la tua opinione. – pavi

2
long end=System.currentTimeMillis()+60*10; 
InputStreamReader fileInputStream = new InputStreamReader(System.in); 
BufferedReader bufferedReader = new BufferedReader(fileInputStream); 
try { 
    while ((System.currentTimeMillis() < end)) { 
     if (bufferedReader.ready()) { 
      System.out.println(bufferedReader.readLine()); 
     } 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} finally { 
    try { 
     if (bufferedReader != null) { 
      bufferedReader.close(); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
6

Utilizzando BufferedReader.available() come suggerito da Sibbo non è affidabile. Documentazione di available() stati:

ritorni una stima del numero di byte che possono essere letti ... Non è mai corretto usare il valore di ritorno di questo metodo per allocare un buffer.

In altre parole, non è possibile fare affidamento su questo valore, ad es. Può restituire 0 anche se alcuni caratteri sono effettivamente disponibili.

Ho effettuato alcune ricerche e, a meno che non sia possibile chiudere il flusso di input del processo dall'esterno, è necessario ricorrere a una lettura asincrona da un thread diverso. Puoi trovare un esempio su come leggere senza bloccare riga per riga here.


Aggiornamento: Qui è una versione semplificata del codice dal link qui sopra:

public class NonblockingBufferedReader { 
    private final BlockingQueue<String> lines = new LinkedBlockingQueue<String>(); 
    private volatile boolean closed = false; 
    private Thread backgroundReaderThread = null; 

    public NonblockingBufferedReader(final BufferedReader bufferedReader) { 
     backgroundReaderThread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        while (!Thread.interrupted()) { 
         String line = bufferedReader.readLine(); 
         if (line == null) { 
          break; 
         } 
         lines.add(line); 
        } 
       } catch (IOException e) { 
        throw new RuntimeException(e); 
       } finally { 
        closed = true; 
       } 
      } 
     }); 
     backgroundReaderThread.setDaemon(true); 
     backgroundReaderThread.start(); 
    } 

    public String readLine() throws IOException { 
     try { 
      return closed && lines.isEmpty() ? null : lines.poll(500L, TimeUnit.MILLISECONDS); 
     } catch (InterruptedException e) { 
      throw new IOException("The BackgroundReaderThread was interrupted!", e); 
     } 
    } 

    public void close() { 
     if (backgroundReaderThread != null) { 
      backgroundReaderThread.interrupt(); 
      backgroundReaderThread = null; 
     } 
    } 
} 
1

L'unico modo affidabile sarebbe quello di iniziare un thread di lavoro e fare la lettura effettiva al suo interno, mentre il il thread del chiamante controllerebbe la latenza.

Se il thread di lavoro è in attesa più tempo consentito, il thread master lo interrompe e genera un'eccezione.

Problemi correlati