如果我从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中。
让主线程等待该过程完成。
清理所有流。

09-11 19:32
查看更多