Я бы посоветовал вам изменить код так, чтобы вы
- либо оберните детали в объект и выполните операцию закрытия позже
- или вы сразу же используете Reader и закрываете соединение после того, как с ним покончено.
Не передавайте считыватель наружу, не поддерживая соединение.
Ниже несколько упрощенный пример того, как это можно сделать.
Если вам нужно выполнить несколько шагов до того, как вы закончите с Reader, вы не сможете обернуть ResultHandler в блок захвата try {...}. В этом случае вам понадобится другой механизм, чтобы в конечном итоге его закрыть.
Но, судя по описанию вашей проблемы, это может быть не так.
Если вы не хотите блокировать, пока операция не будет завершена (в любом случае, эта операция должна выполняться в фоновом потоке), то вы, вероятно, захотите отправить каждую полученную строку вывода куда-нибудь, где она может быть отображена. В этом случае вы можете предоставить интерфейс, который вы используете для пересылки полученных строк.
Пока считыватель все еще получает выходные данные (пока активен входной поток / соединение), вам, вероятно, потребуется выполнить цикл. Каким-то образом вам нужно выяснить, когда ваша операция завершена.
Например, ваш скрипт может закрыть соединение (со стороны сервера), как только это будет сделано, или вернуть что-то конкретное для вас, что вы можете интерпретировать как конец операции.
public class ResultHandler {
String host;
Connection conn;
BufferedReader reader = null;
public ResultReader(String host) {
this.host = host;
}
public void connect(<params>) throws Exception {
// if you intend to reuse the object, just check that it was properly cleanedup before
close();
conn = new Connection(host);
conn.connect();
... // authentication part
// you might want to move the actual handling to a different method
Session sess = conn.openSession();
sess.execCommand("ascript");
InputStream stdout = new StreamGobbler(sess.getStdout());
br = new BufferedReader(new InputStreamReader(stdout));
}
public BufferedReader getReader() {
return this.reader;
}
public void close() {
If (reader != null) {
reader.close();
}
if (conn != null) {
conn.close();
}
}
public void finalize() {
close();
}
}
synchronized void runScript(<params>) {
ResultHandler handler;
try {
handler = new ResultHandler(host);
handler.connect();
// consume the reader for whatever you need to do
} catch (Exception e) {
e.printStackTrace();
} finally {
// or use try-with-resource and implement the proper interface for that
if (handler != null) {
handler.close();
}
}
}