如果我从java执行该软件,如何知道软件是否写完文件?例如,我正在使用输入文件RawText执行geniatagger.exe,该文件将生成输出文件TAGGEDTEXT.txt。当geniatagger.exe写完TAGGEDTEXT.txt文件后,我可以用这个文件做一些其他人员。问题是 - 我怎么知道geniatagger写完文本文件了?
try{
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("geniatagger.exe -i "+ RawText+ " -o TAGGEDTEXT.txt");
}
答案 0 :(得分:1)
你不能,或者至少不可靠。
在这种特殊情况下,最好的办法是观察过程完成。
您可以将流程'返回代码作为奖励,这可以告诉您是否发生了错误。
如果您实际上在谈论this GENIA tagger,下面是一个演示各种主题的实际示例(请参阅代码下方有关编号注释的说明)。该代码使用v1.0 for Linux进行了测试,并演示了如何安全地运行一个过程,该过程希望输入和输出流管道都能正常工作。
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(...)
更好的界面。
在不同的主题中设置流程管道,其他waitFor()
中的FileInputStream
调用可能永远不会完成。
请注意,我向该进程发送了-i
。根据上述GENIA页面,该命令需要实际输入而不是OutputStream
参数。必须关闭连接到流程的FileOutputStream
,否则程序将继续运行!
将流程结果复制到您正在等待的结果文件{{1}}。
让主线程等到进程完成。
清理所有溪流。
答案 1 :(得分:0)
如果程序在生成输出文件后退出,那么您可以调用Process.waitFor()
让它运行完成然后您可以处理该文件。请注意,您可能不得不耗尽标准输出和错误流(至少在Windows上)以完成该过程。
<强> [编辑] 强>
这是一个未经测试且可能充满问题的例子:
// ...
Process p = rt.exec("geniatagger.exe -i "+ RawText+ " -o TAGGEDTEXT.txt");
drain(p.getInputStream());
drain(p.getErrorStream());
int exitCode = p.waitFor();
// Now you should be able to process the output file.
}
private static void drain(InputStream in) throws IOException {
while (in.read() != -1);
}