我正在追求使用 Java 设计一个命令外壳。我必须立即实现的一项重要功能是“自动完成”,这在按下“tab”键时由命令外壳提供便利。为此,我认为我必须在非阻塞模式下逐个字符地读取输入命令。
不幸的是,据我了解,Java API 都不支持非阻塞输入。也就是说,用于读取输入的 Java API 会等待(阻塞),直到用户点击“Enter”键,这在我的情况下是非常不可取的。另外,我已经下定决心不使用任何第三方 Java 库(如 JLine )。
所以,我不得不求助于 JNI。本机 .C 文件似乎是这样的 -
JNIEXPORT jint JNICALL Java_autoComplete_IOUtils_read_1character(JNIEnv *env, jobject obj)
{
int ch = getch(); // getch() - non-blocking input and doesn't echo the characters
return (jint)ch;
}
以及调用上述本机方法的相应Java方法:
public static String GetLine()
{
int i = 0;
do
{
char variable = (char) read_character(); // Native method is invoked here
System.out.println(variable); // Just printing it for my reference
cmdLine = new StringBuffer(cmdLine).insert(i, variable).toString(); // cmdLine is of type String
i++;
} while ((search(cmdLine.charAt(i - 1), interruptableCharacterArray)) == false);
return (new String(cmdLine));
}
//Checks if the entered character is any one of those keys in the interruptableCharacterArray . As of now , interruptableCharacterArray contains only '\t' (The tab key )
private static boolean search(char charAt,char[] interruptableCharacterArray2)
{
for (int i = 0; i < index; i++)
{
if (interruptableCharacterArray2[i] == charAt)
return true;
}
return false;
}
此外,我可以向您保证,在链接本机 .dll 方面没有任何麻烦。而且,截至目前,“InterruptableCharacterArray”仅包含“\t”(“tab”键)。因此,截至目前的 index 值为 1 。
问题:
1> 控件似乎没有阻塞:
char variable = (char) read_character();
也就是说,它似乎不允许用户在该行通过 Java 控制台输入输入,而这是打算这样做的。而且,即使在 getche() 的情况下也是同样的问题(非阻塞但回声)
相反,在每次迭代中,“变量”都会采用一些默认垃圾值,并在执行以下语句时将其打印在控制台上:
System.out.println(variable);
但是,当 getch() 被 getc(stdin)、getchar() 等阻塞对应物替换时,我的这段代码就像一个魅力。
我无法弄清楚通过 JNI 调用 getch() 究竟是什么问题。
2> 另外,如果建议任何其他替代解决方案来实现相同的效果,我将不胜感激。
先感谢您 !
编辑:命令外壳将在基于 Windows 和 Unix 的操作系统上实现。