(Это вопрос, который мой коллега разместил в другом месте, но я думал, что разместил его здесь, чтобы посмотреть, могу ли я попасть в другую аудиторию.)
Привет всем, Я тестирую возможность написания небольшого java-приложения, которое будет использовать Psexec для запуска удаленных заданий. В ходе тестирования, связывающего stdin и stdout java-программы с psexec, я столкнулся с нечетной ошибкой.
Моя тестовая программа - базовая эхо-программа. Он запускает поток для чтения из stdin, а затем выводит вывод read непосредственно в stdout. При запуске на локальном компьютере, а не в psexec, он работает красиво. Точно так, как должно быть.
Однако, когда я вызываю это из PsExec, первый раз, когда вход передается напрямую в stdout, он теряется. Что делает ошибку действительно bizzare в том, что это только первый раз, когда вход передается непосредственно в stdout, что он потерян. Если входная строка добавлена в другую строку, она работает нормально. Либо строковый литерал, либо переменная String. Однако, если входная строка отправляется непосредственно в stdout, она не проходит. Второй раз, когда он отправляется на stdout, он проходит через штраф - и каждый раз после этого.
У меня полная потеря относительно того, что происходит здесь. Я пытался проверить все возможные ошибки, о которых я могу думать. У меня нет идей. Я пропустил один или это просто что-то внутри psexec?
Вот код, о котором идет речь, он состоит из трех классов (один из которых реализует интерфейс, который представляет собой единую функцию interace).
Основной класс:
public class Main {
public static void main(String[] args) {
System.out.println("Starting up.");
CReader input = new CReader(new BufferedReader(
new InputStreamReader(System.in)));
CEcho echo = new CEcho();
input.addInputStreamListener(echo);
input.start();
System.out.println("Successfully started up. Awaiting input.");
}
}
Класс CReader, который является потоком, который читает из stdin:
public class CReader extends Thread {
private ArrayList<InputStreamListener> listeners =
new ArrayList<InputStreamListener>();
private boolean exit = false;
private Reader in;
public CReader(Reader in) {
this.in = in;
}
public void addInputStreamListener(InputStreamListener listener) {
listeners.add(listener);
}
public void fireInputRecieved(String input) {
if(input.equals("quit"))
exit = true;
System.out.println("Input string has made it to fireInputRecieved: "
+ input);
for(int index = 0; index < listeners.size(); index++)
listeners.get(index).inputRecieved(input);
}
@Override
public void run() {
StringBuilder sb = new StringBuilder();
int current = 0, last = 0;
while (!exit) {
try {
current = in.read();
}
catch (IOException e) {
System.out.println("Encountered IOException.");
}
if (current == -1) {
break;
}
else if (current == (int) '\r') {
if(sb.toString().length() == 0) {
// Extra \r, don't return empty string.
continue;
}
fireInputRecieved(new String(sb.toString()));
sb = new StringBuilder();
}
else if(current == (int) '\n') {
if(sb.toString().length() == 0) {
// Extra \n, don't return empty string.
continue;
}
fireInputRecieved(new String(sb.toString()));
sb = new StringBuilder();
}
else {
System.out.println("Recieved character: " + (char)current);
sb.append((char) current);
last = current;
}
}
}
}
Класс CEcho, который является классом, который возвращает его обратно в стандартный вывод:
public class CEcho implements InputStreamListener {
public void inputRecieved(String input) {
System.out.println("\n\nSTART INPUT RECIEVED");
System.out.println("The input that has been recieved is: "+input);
System.out.println("It is a String, that has been copied from a " +
"StringBuilder toString().");
System.out.println("Outputting it cleanly to standard out: ");
System.out.println(input);
System.out.println("Outputting it cleanly to standard out again: ");
System.out.println(input);
System.out.println("Finished example outputs of input: "+input);
System.out.println("END INPUT RECIEVED\n\n");
}
}
И, наконец, вот вывод программы:
>psexec \\remotecomputer "C:\Program Files\Java\jre1.6.0_05\bin\java.exe" -jar "C:\Documents and Settings\testProram.jar" PsExec v1.96 - Execute processes remotely Copyright (C) 2001-2009 Mark Russinovich Sysinternals - www.sysinternals.com Starting up. Successfully started up. Awaiting input. Test Recieved character: T Recieved character: e Recieved character: s Recieved character: t Input string has made it to fireInputRecieved: Test START INPUT RECIEVED The input that has been recieved is: Test It is a String, that has been copied from a StringBuilder toString(). Outputting it cleanly to standard out: Outputting it cleanly to standard out again: Test Finished example outputs of input: Test END INPUT RECIEVED