hasNext() - 什么时候会阻塞,为什么会阻塞?

5
我正在尝试通过Scanner对象读取命令。为了检查输入语法,我使用sc.hasNext()(对于缺少命令的情况)。这已经适用于许多情况,但现在我遇到了JavaAPI中描述的“可能阻塞并等待输入”的情况。 hasNext()方法何时会阻塞,我如何控制它?有趣的是,在阻塞之前,它可以完美地处理3个案例。此外,JavaAPI将hasNext()描述为检查是否有其他输入的适当方法,以便方法next()不会产生Exception
以下是我迄今为止编写的代码:
if (sc.hasNext() && sc.next().equals("create")) {
    if (sc.hasNextInt()) {
        width = sc.nextInt();
        if (width > 0) {
            if (sc.hasNextInt()) {
                heigth = sc.nextInt();
                if (heigth > 0) {
                    if (sc.hasNext()) {  //At this point the hasNext Statement blocks for //no reason till an Input is made.
                        charset = sc.next();
                        Image = new AsciiImage(width, heigth,charset);
                    } else {
                        ret = false;
                        System.out.println("INPUT MISMATCH");
                    }
                } ...//and so on

提前感谢你,我自己找不到关于这个话题的任何信息。 编辑:扫描仪被定义为System.in,但这不应该是一个问题——至少到现在为止还没有出现过。


4
如果没有可用的输入,你认为 hasNext 应该返回什么?除了阻塞直到看到流的结尾或下一个标记,它如何知道是否会有下一个标记?如果没有可用的输入,hasNext 应该返回 false。除非一直阻塞直到看到流的结尾或下一个标记,否则它无法知道是否会有下一个标记。 - Jon Skeet
只有当API中说有另一个标记时,才返回true。这有点奇怪...我应该使用什么代替呢? 此外,在我的程序中,它与每个其他hasNext语句一起工作 - 在每种情况下:没有输入--> false --> break。 - Haini
1
你试图做什么并不清楚。你需要理解扫描器基于流输入 - 如果当前没有数据可用但流没有关闭,则可能会有更多的数据... 它必须等待那些信息才能返回任何有用的东西。 - Jon Skeet
你正在使用阻塞IO,并通过调用hasNext()请求输入。它将会阻塞直到有输入(并返回true),或者底层流被关闭(并返回false)。 - Brian Roach
看起来你有点正确,而我完全误解了hasNext()...我用它来检查是否有更多的条目。在while循环中这是完全可以的,如果我想检查下一个单词是否为整数,那么这是有意义的。 嗯,我有点假设错误了。 感谢你的建议,由于这对其他人并不真正相关,我应该删除这个问题吗? - Haini
请查看此处 http://stackoverflow.com/a/44096029/3351097 。看起来这是与您遇到的问题相同。 - Maxian Nicu
3个回答

9

通过控制台或文本文件进行测试是有区别的。如果我从控制台读取程序,它将期望一个流,并且将等待进一步的输入。

当通过文本文件进行输入测试(仍然使用Java程序中的Scanner的System.in),在文件结束时hasNext()将返回false,因为无法进行进一步的输入。

我无法在此主题的https://docs.oracle.com/javase/9/docs/api/java/util/Scanner.html#hasNext--中找到文档。因此,如果有人找到适当和技术正确的答案,我将非常感激。


1
如果您在等待用户输入时没有其他事情要做,那么被阻塞在调用中直到下一个输入到达是可以的。
如果您想在等待输入时运行其他代码,请生成新线程并从其中调用 hasNext 和其他阻塞扫描器方法。

1
我必须检查命令的正确语法,例如:create int int String。如果三个参数中的任何一个未输入,则应显示错误。 似乎测试我的程序的服务器以不同的方式输入数据,很可能只是从文本文件中读取,其中不期望进行更改,并且hasNext()返回false。我通过控制台进行了测试--> hasNext()等待。 无论如何,谢谢。 - Haini

1
我不确定,但以下是我的个人经验:
当Scanner对象被输入文件时,它不会阻塞!
“输入文件”一词的意思是,Scanner像这样构建:
Scanner scanner = new Scanner("myFile.txt");
但是,如果使用Socket对象的getInputStream()方法构建扫描仪,则如下所示:
input = socket.getInputStream();
Scanner scanner = new Scanner(input);

扫描器将会阻塞!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接