如果我从Java执行该软件,如何知道该软件是否已完成写入文件的操作?例如,我正在执行geniatagger.exe,输入文件RawText会生成输出文件TAGGEDTEXT.txt。 geniatagger.exe写完TAGGEDTEXT.txt文件后,我可以使用该文件做其他工作。问题是-我怎么知道geniatagger已完成文本文件的编写?
try{
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("geniatagger.exe -i "+ RawText+ " -o TAGGEDTEXT.txt");
}
最佳答案
您不能,或者至少不可靠。
在这种情况下,您最好的选择是观看过程的完成。
您将获得流程的返回码作为奖励,这可以告诉您是否发生错误。
如果您实际上是在谈论this GENIA tagger,下面是一个实际的示例,它演示了各种主题(请参阅代码下方有关带编号的注释的说明)。该代码已在Linux v1.0上进行了测试,并演示了如何安全运行一个期望输入和输出流管道正常运行的过程。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.concurrent.Callable;
import org.apache.commons.io.IOUtils;
public class GeniaTagger {
/**
* @param args
*/
public static void main(String[] args) {
tagFile(new File("inputText.txt"), new File("outputText.txt"));
}
public static void tagFile(File input, File output) {
FileInputStream ifs = null;
FileOutputStream ofs = null;
try {
ifs = new FileInputStream(input);
ofs = new FileOutputStream(output);
final FileInputStream ifsRef = ifs;
final FileOutputStream ofsRef = ofs;
// {1}
ProcessBuilder pb = new ProcessBuilder("geniatagger.exe");
final Process pr = pb.start();
// {2}
runInThread(new Callable<Void>() {
public Void call() throws Exception {
IOUtils.copy(ifsRef, pr.getOutputStream());
IOUtils.closeQuietly(pr.getOutputStream()); // {3}
return null;
}
});
runInThread(new Callable<Void>() {
public Void call() throws Exception {
IOUtils.copy(pr.getInputStream(), ofsRef); // {4}
return null;
}
});
runInThread(new Callable<Void>() {
public Void call() throws Exception {
IOUtils.copy(pr.getErrorStream(), System.err);
return null;
}
});
// {5}
pr.waitFor();
// output file is written at this point.
} catch (Exception e) {
e.printStackTrace();
} finally {
// {6}
IOUtils.closeQuietly(ifs);
IOUtils.closeQuietly(ofs);
}
}
public static void runInThread(final Callable<?> c) {
new Thread() {
public void run() {
try {
c.call();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}.start();
}
}
使用
ProcessBuilder
开始您的过程,它的界面比普通的Runtime.getRuntime().exec(...)
更好。在不同的线程中设置流管道,否则({5})中的
waitFor()
调用可能永远无法完成。请注意,我通过管道将
FileInputStream
传递给该进程。根据上述GENIA页面,此命令需要实际输入而不是-i
参数。连接到进程的OutputStream
必须关闭,否则程序将继续运行!将过程的结果复制到您正在等待的结果文件
FileOutputStream
中。让主线程等待该过程完成。
清理所有流。