Получить вывод командной строки в строку в Java
мне нужен метод java, который будет читать вывод командной строки и хранить его в строке для чтения в Java.
это то, что у меня есть до сих пор, но работает неправильно.
public void testGetOutput() {
System.out.println("nn****This is the testGetOutput Method!****");
String s = null;
String query = "dir " + this.desktop;
try {
Runtime runtime = Runtime.getRuntime();
InputStream input = runtime.exec("cmd /c " + query).getInputStream();
BufferedInputStream buffer = new BufferedInputStream(input);
BufferedReader commandResult = new BufferedReader(new InputStreamReader(buffer));
String line = "";
try {
while ((line = commandResult.readLine()) != null) {
s += line + "n";
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}//end testGetOutput()
Я думаю, проблема в том, когда я пытаюсь изменить запрос на команду, которая будет выполнять HandBrakeCLI.исполняемый. Глядя на мою систему, когда программа работает (но, похоже, приостановилась), она показывает мне, что HandBrakeCLI.exe работает под окном cmd, которое запускается под моей IDE. Все это имеет смысл, но HandBrakeCLI.exe не выходит, поэтому я предполагаю, что именно поэтому я не могу прочитать вывод как вход в мою программу.
Итак, после этого фон. Мой большой вопрос: как мне получить HandBrakeCLI.exe, чтобы закрыть после завершения моего запроса, чтобы я мог получить его вывод? Просто для дополнительной информации, единственное различие между метод и метод сканирования DVD я уже HandBrakeCLI-это переменная запроса разный. Вроде этого пример:
String query = "C:UsersKentDesktopHBCLIHandBrakeCLI -t --scan -i "C:UsersKentDesktopGeneral Conference DVDsSources4th October 2004DVD 1"; //this is actually a variable in the DVD object, but here's an example'
О, и, кстати, когда я запускаю этот запрос в обычной командной строке, он делает именно то, что я хочу, давая мне все выходные данные, которые я отчаянно желаю!
вот оригинальная проблема (я не уверен, как повторно отправить вопрос):
Я искал везде и не могу разобраться. Я не уверен, что то, что я нашел, имеет отношение к тому, что я хочу сделать. У меня еще нет много кода для этого, поэтому он не будет много делать, чтобы поместить код здесь и я думаю, что это должно быть довольно просто, поэтому я собираюсь дать несколько скриншотов здесь. Итак, вот моя задача:
папка сканирования, которая полна разорванных папок DVD (Video_TS папки с файлами VOB и т.д.) и сохраните эти имена папок в качестве заголовка DVD.
сканируйте каждую папку с помощью HandBrakeCLI и сохраните вывод в строку.
регулярное выражение строки для идентификации каждого заголовка, главы и язык.
генерировать запросы, чтобы вернуть HandBrakeCLI для массового кодирования каждого языка в каждой главе в каждом заголовке для каждого DVD (вы можете понять, почему я хочу автоматизировать это!)
Сохраните эти запросы в *.bat файл
только я не уверен, что это шаг 2! Все остальное я могу сделать довольно легко. Я много читал о OutputStreams, но я просто не могу понять, как это работает. Я просто ... нужно получить вывод в строку, которую я могу regex, чтобы получить материал, который мне нужен. Вот скриншоты того, что мне нужно ввести и что мне нужно удалить с выхода:
вход в HandBrakeCLI:
выход для сканирования:
3 ответов
сначала вам нужен неблокирующий способ чтения из Standard.out
и Standard.err
private class ProcessResultReader extends Thread
{
final InputStream is;
final String type;
final StringBuilder sb;
ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type)
{
this.is = is;
this.type = type;
this.sb = new StringBuilder();
}
public void run()
{
try
{
final InputStreamReader isr = new InputStreamReader(is);
final BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
this.sb.append(line).append("\n");
}
}
catch (final IOException ioe)
{
System.err.println(ioe.getMessage());
throw new RuntimeException(ioe);
}
}
@Override
public String toString()
{
return this.sb.toString();
}
}
тогда вам нужно связать этот класс с соответствующим InputStream
и OutputStream
объекты.
try
{
final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query));
final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR");
final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT");
stderr.start();
stdout.start();
final int exitValue = p.waitFor();
if (exitValue == 0)
{
System.out.print(stdout.toString());
}
else
{
System.err.print(stderr.toString());
}
}
catch (final IOException e)
{
throw new RuntimeException(e);
}
catch (final InterruptedException e)
{
throw new RuntimeException(e);
}
это в значительной степени котельная плита, которую я использую, когда мне нужно Runtime.exec()
что-нибудь на Java.
более продвинутым способом было бы использовать FutureTask
и Callable
или хотя бы Runnable
вместо прямого расширения Thread
что не самое лучшее практиковать.
Примечание:
на @Nonnull
аннотации находятся в библиотеке JSR305. Если вы используете Maven, и вы используете Maven не вы, просто добавьте эту зависимость в свой pom.xml
.
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
</dependency>
этот полный пример программы Java запускает команду " dir " (список каталогов) в командной строке и вытягивает результат в строку и печатает его на консоли.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class X {
public static void main(String[] args) {
try{
String command = "dir";
String s = get_commandline_results(command);
System.out.println(s);
}
catch(Exception e){
e.printStackTrace();
}
System.out.println("done");
}
public static String get_commandline_results(String cmd)
throws IOException, InterruptedException, IllegalCommandException{
//Do not remove the authorizedCommand method. Be prepared
//to lose your hard drive if you have not white-listed the
//commands that can run.
if (!authorizedCommand(cmd))
throw new IllegalCommandException();
String result = "";
final Process p = Runtime.getRuntime().
exec(String.format("cmd /c %s", cmd));
final ProcessResultReader stderr = new ProcessResultReader(
p.getErrorStream(), "STDERR");
final ProcessResultReader stdout = new ProcessResultReader(
p.getInputStream(), "STDOUT");
stderr.start();
stdout.start();
final int exitValue = p.waitFor();
if (exitValue == 0){
result = stdout.toString();
}
else{
result = stderr.toString();
}
return result;
}
public static boolean authorizedCommand(String cmd){
//Do not allow any command to be run except for the ones
//that we have pre-approved here. This lessens the
//likelihood that fat fingers will wreck your computer.
if (cmd.equals("dir"))
return true;
//add the commands you want to authorize here.
return false;
}
}
class ProcessResultReader extends Thread{
final InputStream is;
final String type;
final StringBuilder sb;
ProcessResultReader(final InputStream is, String type){
this.is = is;
this.type = type;
this.sb = new StringBuilder();
}
public void run()
{
try{
final InputStreamReader isr = new InputStreamReader(is);
final BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
this.sb.append(line).append("\n");
}
}
catch (final IOException ioe)
{
System.err.println(ioe.getMessage());
throw new RuntimeException(ioe);
}
}
@Override
public String toString()
{
return this.sb.toString();
}
}
class IllegalCommandException extends Exception{
private static final long serialVersionUID = 1L;
public IllegalCommandException(){ }
}
в Windows, это результат, который я получаю
Directory of D:\projects\eric\eclipseworkspace\testing2
07/05/2012 01:06 PM <DIR> .
07/05/2012 01:06 PM <DIR> ..
06/05/2012 11:11 AM 301 .classpath
06/05/2012 11:11 AM 384 .project
06/05/2012 11:11 AM <DIR> .settings
07/05/2012 01:42 PM <DIR> bin
06/05/2012 11:11 AM <DIR> src
07/05/2012 01:06 PM 2,285 usernames.txt
3 File(s) 2,970 bytes
5 Dir(s) 45,884,035,072 bytes free
done
если вы используете Runtime.exec()
чтобы запустить внешний процесс, давая вам Process
object, есть три соответствующих метода для этого объекта:getOutputStream()
, getInputStream()
и getErrorStream()
.
Я думаю, что легко запутаться в этом-вы, вероятно, думаете, что хотите увидеть результат процесса, поэтому "выходной поток" - это то, что вы хотите. Но вам нужно помнить, что именование этих объектов с точки зрения Java-кода - OutputStream является для Java для записи вывода, в то время как InputStream для Java для чтения ввода. Выход вашего внешнего процесса, с точки зрения Java, является входным.
таким образом, вы будете использовать getInputStream()
и вызовите соответствующие методы на InputStream
возвращенный им для чтения вывода. Вы также можете использовать getErrorStream()
чтобы убедиться, что вы ничего не пропустили, потому что он записан в стандартную ошибку.