2011-10-01 78 views
2

我沒有做Java長。在這個腳本中它說Thread.sleep(10000);你仍然可以鍵入(我使用eclipse)我真的不知道爲什麼它可以讓你輸入輸出,當我沒有uno.nextLine();在10秒鐘之前或之後等待。請幫忙!由於簡單的Java掃描儀問題

import java.util.Scanner; 
class Tutoiral{ 
     public static void main (String args[])throws InterruptedException { 
      Scanner uno = new Scanner(System.in); 
      Scanner uno1 = new Scanner(System.in); 
      System.out.println("What's your name?"); 
      String name = uno.nextLine(); 
      System.out.println("Hi, " + name + ". Feel free to type whatever you want :) BUT DON'T SPAM!!!!!"); 

      String typed = (": ") + uno1.nextLine(); 
      System.out.println(name + typed + " (5 types remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (4 types remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (3 types remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (2 types remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (1 type remaining)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (If you type one more time, then I'll... I'll block you! Ha!)"); 
      uno.nextLine(); 
      System.out.println(name + typed + " (tut tut tut. You have been blocked for a while for spam. Don't type EVER again ok?)"); 
      Thread.sleep(10000); 
      System.out.println("Ok, you can type again. But I wouldn't If I were you."); 

回答

2

我真的不知道爲什麼它可以讓你在輸出輸入的時候我沒有uno.nextLine();

nextLine呼叫將讀取(返回)從標準輸入的字符。如果你看過他們或不控制檯將打印用戶,輸入字符不分。

不幸的是(對於您)不可能阻止用戶輸入標準輸入數據。


一種解決方法可能是禁用「本地回顯」,即避免打印用戶輸入的字符。我不知道如何做到這一點。令人討厭的做法是做System.console().readPassword()

玩了,我想出了以下超討厭的黑客的解決方法(要注意的是Thread.stop()例如,已經廢棄了很好的理由。):

public static void turnOffLocalEcho(long ms) { 
    Thread t = new Thread() { 
     public void run() { 
      while (true) { System.console().readPassword(); } 
     } 
    }; 

    t.start(); 

    try { 
     Thread.sleep(ms); 
    } catch (InterruptedException ie) { 
    } 

    t.stop(); 
} 

只是一個替換您的來電Thread.sleep(10000)調用該方法:

turnOffLocalEcho(10000); 
0

烏諾將處理輸入鍵入每當(睡覺時,工作,或等待輸入)時的其nextSomething()方法被調用。你不需要調用nextSomething()並解析輸入,但是用戶可以以任何方式輸入。

0

控制檯輸入(因此Scanner)不起作用人們想象的方式。

控制檯程序具有稱爲standard input, or stdin的輸入流。您可以將其視爲程序讀取的字符隊列。

當鍵入一個字符到一個控制檯程序,它通常具有2種效果:

  1. 終端立即打印字符到屏幕上。
  2. 字符被附加到程序的標準輸入。 (從技術上講這隻能每次鍵入一個換行符(輸入)發生。)

這些行動是由操作系統執行的,所以無論你的計劃目前正在從標準輸入讀取數據,他們的工作。如果程序正在等待數據,它將立即處理它(忽略輸入流緩衝)。但是,如果沒有(例如,它正在處理其他事情,或者在你的情況下睡10秒),角色就在隊列中,直到程序讀取它爲止。

Scanner實際上並沒有提示用戶輸入一行文字。工作原理:當一個程序嘗試從標準輸入讀取數據時,如果沒有可用的數據,程序將阻塞,直到操作系統爲其提供足夠的數據Scanner.nextLine()從標準輸入讀取字符,直到讀取換行符,此時它將返回自上一個換行符以來輸入的字符。這意味着通常,Scanner.nextLine()將導致程序等待,直到用戶按Enter鍵。

但是,請注意,如果您一次輸入多行文本,例如通過將幾行代碼粘貼到終端中,或通過外殼管道或重定向(例如java MyProgram < file.txt),程序將繼續運行,直到它已經吃掉了所有的輸入。

當您的程序正在休眠時,用戶仍然可以鍵入並追加到程序的標準輸入中! (嘗試在程序結尾處添加System.out.println(name + typed + uno.nextLine());的幾個副本,並查看當您的程序在睡覺時鍵入時會發生什麼。)

因此,要防止用戶鍵入主程序將讀取的內容,請當你的主線程睡眠時需要做兩件事:

  1. 告訴控制檯停止輸入到控制檯的回顯字符。
  2. 讀取提供給stdin的任何字符,並丟棄它們。

您可以通過在另一個線程中調用System.console().readPassword()來完成這兩個操作(並放棄其輸出)。這樣,在10秒鐘後,主線程將喚醒並終止密碼讀取線程。但到那時,用戶在主線程休眠時鍵入的任何內容都將被讀取(從標準輸入刪除)並被其他線程丟棄,因此實際上用戶無法在控制檯上鍵入。 (請參閱aioobe對此代碼的回答。)