2010-10-24 9 views
17

Il programma qui sotto stampa ogni carattere scritto sullo standard in, ma solo dopo che è stata scritta una nuova riga (almeno sul mio sistema!).Perché non possiamo leggere un carattere alla volta da System.in?

public class Test { 
    public static void main(String[] args) throws java.io.IOException { 
     int c; 
     while ((c = System.in.read()) != -1) 
      System.out.print((char) c); 
    } 
} 

Questo impedisce alle persone di scrivere cose come "Premere un tasto per continuare" e le forze di qualcosa come "Premere Invio per continuare."

  • Qual è il motivo alla base di questo?
  • È una limitazione di Java?
  • Questo comportamento dipende dal sistema (sono su Ubuntu)? Come funziona su Mac? Finestre?
  • Dipende dal terminale specifico in cui eseguo l'applicazione? (Per me si comporta come questo in Eclipse e in gnome-terminal)
  • C'è una soluzione?
+0

vedere la mia risposta in http://stackoverflow.com/questions/1864076/equivalent-function-to-cs-getch-in-java/10118990#10118990 –

risposta

19

Qual è il motivo alla base di questo?

La maggior parte dei terminali è in modalità bufferizzata per impostazione predefinita, Java non riceve input fino a una nuova riga.

È una limitazione di Java?

Alcuni terminali antichi possono avere solo ingresso con buffer di linea; anche se dovrebbe essere possibile disabilitare il buffering nella maggior parte dei terminali moderni.

Questo comportamento dipende dal sistema (sono su Ubuntu)? Come funziona su Mac? Finestre?

Sì.

Dipende dal terminale specifico in cui eseguo l'applicazione? (Per me si comporta così in Eclipse e in gnome-terminal)

Sì.

C'è una soluzione alternativa?

Ci sono hack specifici della piattaforma. curse in piattaforme Linux e Unix e getch() in Windows. Non sono a conoscenza di alcun modo multipiattaforma.

relativi: Perché "Premere un tasto per continuare" è cattiva idea:

alt text

0

Vedere la mia risposta in Equivalent function to C's "_getch()" in Java?


public static void getCh() {

final JFrame frame = new JFrame(); synchronized (frame) { frame.setUndecorated(true); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); frame.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { synchronized (frame) { frame.setVisible(false); frame.dispose(); frame.notify(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }); frame.setVisible(true); try { frame.wait(); } catch (InterruptedException e1) { } }

}

+4

Questo non viene letto da 'System.in' * a tutto * però. – aioobe

6

I sono su Ubuntu

C'è una soluzione alternativa?

Runtime.getRuntime().exec("stty -icanon min 1").waitFor(); 

E dopo che tutte le letture del System.in nello stesso processo leggerà 1 carattere senza aspettare EOL.

+0

Questo non sembra funzionare a meno che non si usi quanto segue: 'exec (new String [] {"/bin/sh "," - c "," stty -icanon min 1 Kelvin

Problemi correlati