在我的Java应用程序中,有时我必须调用非Java命令行应用程序来处理文件。我经常处理20个文件,对于每个文件,我使用 Runtime.getRuntime()。exec 来运行命令,附加一个进程以侦听输出和错误输出,并等待任务完成。 / p>
在我的PC上,它可以正常工作,但是在相当慢的NAS设备上,通过Java运行任务的速度似乎要慢一些,如果直接从命令行运行它们,则每个任务持续几秒钟,可能还要再花几秒钟比从命令行。随着时间的流逝,这种明显的差异是相当大的(在PC上注意,每个任务仅花费大约200毫秒)。
从Java调用,创建线程以侦听输出并等待完成会产生大量开销。我是否应该重写代码以创建一个可以处理所有文件的脚本,所以我只需要一个 Runtime.getRuntime()。exec 和两个Strokem Gobbler。
因为我需要考虑有时会失败的任务,所以困难在于可靠地解析输出,所以我的问题是,是否有任何意义,会有所作为?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class StreamGobbler implements Runnable {
private InputStream inputStream;
private StringBuilder output;
public StreamGobbler(InputStream inputStream, StringBuilder output) {
this.inputStream = inputStream;
this.output = output;
}
@Override
public void run()
{
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
try
{
String s = br.readLine();
if (s != null)
{
output.append(s);
}
br.close();
}
catch(IOException ioe)
{
}
}
}
List<String> params = new ArrayList();
params.add(new File(SongKong.exeFolder, "fpcalc").getAbsolutePath());
params.add(file.getPath());
p = Runtime.getRuntime().exec(params.toArray(new String[1]));
StringBuilder output = new StringBuilder();
StringBuilder errorOutput = new StringBuilder();
StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), output);
StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), errorOutput);
Executors.newSingleThreadExecutor().execute(outputGobbler);
Executors.newSingleThreadExecutor().execute(errorGobbler);
p.waitFor();
fingerprint = output.toString();
答案 0 :(得分:0)
您想知道是否重写应用程序以执行脚本而不是多个exec会影响执行时间。
可能会。但是,如果不了解exec命令执行速度为何缓慢,我们就无法告诉您它会产生多大的变化……以及是否值得付出努力。
我建议您使用Java做一些简单的实验:
比较运行某些简单命令(例如exec("echo hello")
)20次,而不是执行执行相同操作的脚本:
做同样的事情,涉及存储在NAS上的输入文件
执行涉及存储在NAS上的可执行文件的操作(如果相关)
这些实验应该可以帮助您确定建议的加速应用程序的方法是否可行。
如果您的外部命令是在类路径上具有许多JAR且这些JAR位于NAS上的Java命令,那么可能会严重影响启动时间。 / p>