Java 进程等待

Java process waitFor

我有以下使用 gvim 将源代码转换为 html 的方法:

    String code2html( String s ) throws Exception {
    if ( s == null || s.length() == 0 ) return "";
    String txtfile = "dummyFile"+(UUID.randomUUID().toString())+".txt";
    String t;
    //PrintWriter w = new PrintWriter(Konst.FPATH+"tmp.txt","UTF-8");
    File fl = new File(Konst.FPATH+txtfile);
    FileWriter fw = new FileWriter(fl);
    PrintWriter w = new PrintWriter(fw);
    w.println(s);
    w.close();
    Runtime rt = Runtime.getRuntime();
    String T;
    try {
        // Process pr = rt.exec(T = "gvim -c \"set syntax=Java\" -c \"wq\" -c \"q\" "+Konst.FPATH+"tmp.txt");
        //Process pr = rt.exec(T = "gvim "+Konst.FPATH+"tmp.txt -s "+Konst.FPATH+"scrip.vim");
        Process pr = rt.exec(T = "gvim "+Konst.FPATH+txtfile+" -s "+Konst.FPATH+"scrip.vim");
        System.out.println(T);
        FileOutputStream fos;

        StreamGobbler errorGobbler = new StreamGobbler(pr.getErrorStream(),"ERROR");
        StreamGobbler outputGobbler = new StreamGobbler(pr.getInputStream(),"OUTPUT",fos=new FileOutputStream(Konst.FPATH+"garbage.out"));

        errorGobbler.start();
        outputGobbler.start();

        fos.flush();
        fos.close();
        int exitVal = pr.waitFor();

        StringBuilder sb = new StringBuilder();

        //BufferedReader b = new BufferedReader(new FileReader(Konst.FPATH + "tmp.txt.html"));
        if ( exitVal == 0 ) {
            BufferedReader b = new BufferedReader(new FileReader(Konst.FPATH + txtfile + ".html"));
            while ((t = b.readLine()) != null && !(t.length() >= 5 && t.substring(0, 5).equals("<body"))) ;
            do {
                sb.append(t + "\n");
            } while ((t = b.readLine()) != null && !(t.length() >= 6 && t.substring(0, 6).equals("</body")));
            sb.append(t);
            return sb.toString();
        }
        else return "";
    }
    catch ( Throwable e ) {
        e.printStackTrace();
    }
    return "";
}

相关的 StreamGobbler 在这里:

class StreamGobbler extends Thread {
InputStream is;
String type;
OutputStream os;

StreamGobbler( InputStream is, String type ) {
    this(is,type,null);
}
StreamGobbler( InputStream is, String type, OutputStream os ) {
    this.is = is; this.type = type; this.os = os;
}
@Override
public void run() {
    try {
        PrintWriter pw = null;
        if (os != null) {
            pw = new PrintWriter(os);
        }
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader r = new BufferedReader(isr);
        String line = null;
        while ((line = r.readLine()) != null) {
            if (pw != null)
                pw.print(line);
            System.out.println(type + ">" + line);
        }
        if (pw != null)
            pw.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

因此,gvim 应该将源代码转换为名为 dummy+random string.html 的 html 文件。它确实如此。只是当 BufferedReader 读取文件时,它没有找到它 ("No such file or directory"),尽管文件确实出现在相关文件夹中。因此,显然文件是在 BufferedReader 尝试访问之后创建的,尽管有 waitFor() 命令。如何解决这个问题?

有时 Runtime#exec 完成一个进程后,需要一些时间才能完成 IO 操作。因此,请尝试在 Process#waitFor 之后使用 Thread#sleep 进行一些延迟,以使 IO 处理完成。然后尝试读取目标文件。

希望对您有所帮助。