如何在不阻塞的情况下从控制台接收输入?

时间:2014-08-06 23:43:17

标签: java console nonblocking

注意:我知道控制台用于调试,游戏应该使用GUI。这是用于测试/体验

我正在写一个以60fps运行的游戏。每次更新,我都会检查用户是否输入了String命令。如果是这样,它会被传递,但如果没有,则null是paas through,而null将被忽略。

扫描仪是不可能的,因为hasNext()用于查看是否有要读取的数据的方法可能会阻塞并导致问题。

我尝试过使用BufferedReader.ready()。我不仅遇到了问题(从未返回true),但我读过因为一些原因不建议这样做。

BufferedReader.available()总是返回0,在文档中,它声明InputStream.available()将始终返回0,除非重写。这是我的尝试:

class Game {

     public static void main(String[] args) {
          InputReader reader = new InputReader(System.in);
          int timePerLoop = 1000/30;

          Game game = new Game();
          while(true) {
               long start = System.nanoTime();
               game.update(reader.next());
               long end = System.nanoTime();

               long sleepTime = timePerLoop + ((start - end) / 10000000);
               if(sleepTime > 0)
                    try {
                         Thread.sleep(sleepTime);
                    }catch(InterruptedException e) {
                         e.printStackTrace();
                    }
               else
                    Thread.yield();
          }
     }

     public void update(String command) {
          if(commands != null) {
               //handle command
          }

          //update game
     }
}

InputReader.java

public class InputReader {
     private InputStream in;

     public InputReader(InputStream stream) {
          in = stream;
     }

     public String next() {
          String input = null;
          try {
               while(in.available > 0) {
                    if(input == null)
                         input = "";

                    input += (char) in.read();
               }
          }catch(IOException e) {
               e.printStackTrace();
          }
          return input;
     }
}

InputStream本身具有与上述相同的问题。我不完全确定System.in中存储的对象的类型,但使用available()会产生相同的结果。

我尝试使用reader()中的System.console(),但console()返回null。我已经读过这个主题了,我并不感到困惑。这不是这样做的方法。

目标是检查流以查看它是否包含要读取的数据,这样我就可以读取数据,因为它知道它不会阻塞。

我不想使用单独的Thread来处理用户输入,因此请不要推荐或询问原因。

输入必须来自控制台。在此过程中不会创建新的套接字。我已经阅读了一些关于它的主题,但没有一个明确说明了解决方案。 这可能吗?

1 个答案:

答案 0 :(得分:1)

正如您自己所说,自定义GUI或其他线程是执行此操作的正确方法。但是,如果没有,请尝试使用readLine(),例如:String inputR = System.console().readLine();

对main()的一些改动:

替换:InputReader reader = new InputReader(System.in);Console c = System.console();

替换:game.update(reader.next()); 用:game.update(c.readLine());

编辑:此主题也可能有所帮助:Java: How to get input from System.console()