Я занимаюсь разработкой командной оболочки с использованием Java. Одной из важных функций, которые я должен был немедленно реализовать, была «автоматическая комплектация», что облегчалось командной оболочкой при нажатии клавиши «tab». Для этого я считал, что мне нужно прочитать команду ввода, по-символу в режиме без блокировки.Неблокирующий вход в Java, реализованный через JNI
К сожалению, как я понял, ни один из поддерживающих 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»). Следовательно, значение индекса на данный момент равно 1.
Probelm:
1> Контроль не кажется, чтобы блокировать по адресу:
char variable = (char) read_character();
То есть, это, кажется, не позволяет пользователю ввести вход через Java Консоль на этой линии, которая предназначена для этого. И это также проблема даже в случае getche() (Non-blocking, но эхо)
Вместо этого на каждой итерации берется значение по умолчанию для «переменной», которое печатается на консоли, когда следующее утверждение выполняется:
System.out.println(variable);
Однако этот код шахты работает как шарм, когда Геч() заменяется ее блокирующих аналогами как ЕОКП (стандартный ввод), GetChar() и т.д..
Я не могу понять, что именно является проблемой при вызове getch() через JNI.
2> Кроме того, я был бы признателен, если бы предложили другие альтернативные решения для достижения того же.
Заранее благодарю вас!
Редактировать: Командная оболочка должна быть реализована как на ОС Windows, так и на основе Unix.
То, что вы хотите, не «неблокирующим» IO, но «сырой» выходовспомощьютерминал. Я предлагаю вам посмотреть на вещи, такие как stty – Ingo
@Ingo: Большое спасибо! Что относительно Windows O/S? – bsv0099
Обратите внимание на ссылки, которые Аарон опубликовал. JLine2 явно обрабатывает терминалы Windows, поэтому вы можете получить идеи там. BTW, чтобы стать хорошей средой переполнения стека, вы должны проголосовать за полезные ответы и принять лучшее. Я думаю, что должность Аарона заслуживает этого. – Ingo