这个问题令我难过。我写了一个从循环内部调用的方法。它第一次完美运行,之后就会挂起。
这是方法:
public static String promptUser(){
String path = "";
Scanner reader = new Scanner(System.in);
while (!path.contains(ROOT_FOLDER)){
System.out.println(String.format("Please paste in the directory path from WinSCP, including %s: ", ROOT_FOLDER));
while (true) {
if (reader.hasNext()){
path = reader.nextLine();
break;
}
}
}
reader.close();
return path;
}
这是循环
while (true) {
try {
listFiles(promptUser());
break;
}
catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}
我第一次运行它时,会提示用户多次获取我们需要的信息(目录路径)。然后它向FTP服务器发送请求,如果该路径不存在,我希望它继续提示用户。但我的调试器在第二轮就告诉我它只是挂起:
if (reader.hasNext()){
按Enter键不会让它继续。在第一次调用promptUser时,我可以输入没有根文件夹的东西,它会一直询问,直到它获得根文件夹。那么为什么不在第二次调用时这样做呢?
发生了什么事?
答案 0 :(得分:2)
第一次拨打promptUser
时,会执行以下操作:
Scanner
。{/ li>的System.in
Scanner
。问题在于第4步。当您关闭Scanner
时,您也关闭System.in
。
下次致电promptUser
Scanner
的另一个System.in
。此时System.in
已关闭。hashNext()
,会立即返回false
...因为Scanner
包裹的信息流已关闭。解决方案:不要关闭System.in
或包裹它的Scanner
。并且不要创建包裹Scanner
的第二个System.in
。相反,重用原始Scanner
。
但是有必要在某个时候关闭扫描仪吗?
您永远不需要关闭包裹(原始)Scanner
流的System.in
。我们关闭流的原因是:
泄漏文件描述符的问题是进程(即您的JVM)一次只能打开一定数量的文件。如果泄漏文件描述符,您可能会发现打开文件的尝试因意外IOException
而开始失败。
在System.in
的情况下,没有要写入的数据。由于您无法再次打开System.in
(因为您不知道它连接到的是什么),因此最多只有一个文件描述符可以被泄露"所以这不是问题
Eclipse警告我应该这样做。
关于关闭扫描仪等的Eclipse启发式算法相当简单。在这种情况下,警告可能是一个误报警,虽然我需要看到代码是确定的。
答案 1 :(得分:1)
获取下一个元素时,不应在循环内使用break
。这会导致您的while(true)
循环退出。这意味着你得到第一个项目并完成。
您应该将其更改为:
while(reader.hasNext()) {
path = reader.nextLine();
// do something with the path here...
}
答案 2 :(得分:-1)
阅读hasNext()
如果此扫描器的输入中有另一个标记,则返回true。在等待输入扫描时,此方法可能会阻塞。扫描仪不会超过任何输入。 返回: 当且仅当此扫描器具有另一个令牌时才为真
所以,hasNext()等着你输入一些值。它会等到找到用户输入的单个字符串。