[英]java get output of batch file command by command
I need to execute .bat
files in my java application. 我需要在Java应用程序中执行.bat
文件。 Suppose I have a text file with this sample content: 假设我有一个文本文件,其中包含以下示例内容:
{
"id": 12,
"name": "test"
}
And in my .bat
file, I have a command for outputing text file content. 在我的.bat
文件中,我有一个用于输出文本文件内容的命令。 So this is my .bat
file content: 这是我的.bat
文件内容:
#some other commands
more path\to\file.txt
And finally, this is my java code for executing this .bat
file: 最后,这是我执行该.bat
文件的Java代码:
Process process = Runtime.getRuntime().exec("path\to\file.bat");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
List<String> outputs = new ArrayList<>();
while ((line = reader.readLine()) != null) {
outputs.add(line);
}
After executing this code, the outputs
list has data something like this: 执行此代码后, outputs
列表中的数据如下所示:
[...,
"{",
" "id": 12",",
" "name": "test",",
"}"
]
I means, this returns output line by line . 我的意思是,这将逐行返回输出。 But I want to have whole command output as one index of my list. 但我想将整个命令输出作为列表的一个索引。 In the other words, I want to have command by command instead of line by line output (every command has just one output). 换句话说,我想要逐个命令而不是逐行输出 (每个命令只有一个输出)。
Is this possible doing something like that? 这样可以做吗?
Edit: I tried using ProcessBuilder
also, but result was the same. 编辑:我也尝试使用ProcessBuilder
,但结果是相同的。
You claim 你声称
And in my
.bat
file, I have a command for outputing text file content. 在我的.bat
文件中,我有一个用于输出文本文件内容的命令。
and 和
I want to have command by command instead of line by line output (every command has just one output). 我想要逐个命令而不是逐行输出 (每个命令只有一个输出)。
If I'm understanding this correctly, that means that you run your code only once (one "command") every time that you want to output a file. 如果我正确理解这一点,则意味着每次要输出文件时,您仅运行一次代码(一个“命令”)。 That is, you're only requiring that the outputs described are joined together in a single line, at which point you can put the lines in a list. 也就是说,您只需要将描述的输出连接到一行中即可,此时您可以将这些行放在列表中。 This can be achieved like so: 可以这样实现:
Process process = Runtime.getRuntime().exec("path\to\file.bat");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder builder = new StringBuilder();
List<String> outputs = new ArrayList<>();
//if desired, append prefix
//builder.append("File: {");
while ((line = reader.readLine()) != null) {
builder.append(line);
//if desired, append delimiter
//builder.append("\n");
}
//if desired, append suffix
//builder.append("}");
String concatenatedString = builder.toString();
Alternatively, in Java 8+, you can do the following (and even specify details of how lines are joined together): 另外,在Java 8+中,您可以执行以下操作(甚至指定有关如何将线连接在一起的详细信息 ):
Process process = Runtime.getRuntime().exec("path\to\file.bat");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String concatenatedString = reader.lines().collect(Collectors.joining(" "));
Naturally, I'm assuming that you're just using the example of reading files as a proxy for another where you must actually read a process' output. 自然地,我假设您只是使用读取文件的示例作为另一个文件的代理,在该文件中您实际上必须读取进程的输出。 If all you require is a file read, a Process is not required to achieve this. 如果您只需要读取文件,则不需要过程即可实现。 Instead, you can get file contents as so: 相反,您可以这样获取文件内容:
String concatenatedString = "";
try (Stream<String> stream = Files.lines(Paths.get("path\to\text\file.txt"))) {
concatenatedString = stream.collect(Collectors.joining(" "));
}
//catch...
Now, if you actually want to join all text output together from many processes, but only have it as an aggregate (ie you can't join process outputs one by one, then store them), you're going to end up having to do the following: 现在,如果您实际上想将来自多个流程的所有文本输出连接在一起,而只是将其作为一个集合(即,您不能一个接一个地连接流程输出,然后再存储它们),那么最终将不得不请执行下列操作:
append
or Collectors join
as shown above. 如上所示,使用StringBuffer append
或Collectors join
很容易做到这一点。 As @Mofi and @kriegaex stated you should explain the use of batch files. 正如@Mofi和@kriegaex所说,您应该解释批处理文件的用法。 I suppose that you already have them (batch files or some other executables) and you can not get rid of them but instead want to execute them and capture stdout
of each execution into a single List
or Map
item. 我想您已经拥有了它们(批处理文件或其他可执行文件),并且您不能摆脱它们,而是想要执行它们并将每个执行的stdout
捕获到单个List
或Map
项中。
Your current implementation appends each line into List
: 您当前的实现将每行追加到List
:
while ((line = reader.readLine()) != null) { outputs.add(line); }
One solution is to use StringBuilder
to concatenate stdout
lines of each executable. 一种解决方案是使用StringBuilder
连接每个可执行文件的stdout
行。 After that each concatenated output is appended into Map
. 之后,每个串联的输出将附加到Map
。 See this sample: 看到这个例子:
// Create Map for outpus.
Map<String, String> outputs = new HashMap<String, String>();
// Loop through batch files.
for (String bat : new String[] { "file12.bat", "file13.bat" }) {
// Execute batch.
Process process = Runtime.getRuntime().exec(bat);
// Open Reader...
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
// ... and read contents into StringBuilder.
StringBuilder contents = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
contents.append(line);
contents.append("\n"); // Append newline because reader.readLine() omits it.
}
// Close Reader.
reader.close();
// Add contents into Map.
outputs.put(bat, contents.toString());
}
After that you can verify Map
contents for example like this: 之后,您可以验证Map
内容,例如:
for (String bat : outputs.keySet()) {
System.out.print("### output of ");
System.out.print(bat);
System.out.println(" ###");
System.out.println(outputs.get(bat));
}
It looks as if you do not want to perform a System.out.println()
and instead collect all the output of a command and print it in bulk at the end of each command. 好像您不想执行System.out.println()
,而是收集命令的所有输出,并在每个命令的末尾批量打印它。
Well, then, write your own CommandResultCollector
type where you initiate a StringBuffer
and concatenate strings with proper line breaks as part of a single command execution and at the end of the command execution, convert it to a String
and print the whole thing. 好吧,然后编写您自己的CommandResultCollector
类型,在其中您启动StringBuffer
并使用适当的换行符将字符串连接起来,作为单个命令执行的一部分,并在命令执行结束时将其转换为String
并打印整个内容。
Alternatively, you can create an ArrayList
and add all the Strings
that are being printed as part of the command and iterate at the end of the execution to print them all at the end of every command execution. 另外,您可以创建一个ArrayList
并添加作为命令一部分打印的所有Strings
,并在执行结束时进行迭代以在每次命令执行结束时将它们全部打印出来。
I am sure there are better solutions that use the Heap
memory intelligently. 我确信,有更好的解决方案可以智能地使用Heap
内存。 You can solve this problem in many ways, choose the simplest and least resource intensive one. 您可以通过多种方式解决此问题,选择最简单且最少的资源消耗。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.