views:

190

answers:

1

I'm trying to process data obtained from a run of diff to an instance of GNU grep in a java program. I've managed to get the output of diff using the Process object's outputStream, but I'm currently having programs sending this data to the standard input of grep (through another Process object created in Java). Running Grep with the input only returns status code 1. What am I doing wrong?

Below is the code I have so far:

public class TestDiff {
final static String diffpath = "/usr/bin/";

public static void diffFiles(File leftFile, File rightFile) {

    Runtime runtime = Runtime.getRuntime();

    File tmp = File.createTempFile("dnc_uemo_", null);

    String leftPath = leftFile.getCanonicalPath();
    String rightPath = rightFile.getCanonicalPath();

    Process proc = runtime.exec(diffpath+"diff -n "+leftPath+" "+rightPath, null);
    InputStream inStream = proc.getInputStream();
    try {
        proc.waitFor();
    } catch (InterruptedException ex) {

    }

    byte[] buf = new byte[256];

    OutputStream tmpOutStream = new FileOutputStream(tmp);

    int numbytes = 0;
    while ((numbytes = inStream.read(buf, 0, 256)) != -1) {
        tmpOutStream.write(buf, 0, numbytes);
    }

    String tmps = new String(buf,"US-ASCII");

    inStream.close();
    tmpOutStream.close();

    FileInputStream tmpInputStream = new FileInputStream(tmp);

    Process addProc = runtime.exec(diffpath+"grep \"^a\" -", null);
    OutputStream addProcOutStream = addProc.getOutputStream();

    numbytes = 0;
    while ((numbytes = tmpInputStream.read(buf, 0, 256)) != -1) {
        addProcOutStream.write(buf, 0, numbytes);
        addProcOutStream.flush();
    }
    tmpInputStream.close();
    addProcOutStream.close();

    try {
        addProc.waitFor();
    } catch (InterruptedException ex) {

    }

    int exitcode = addProc.exitValue();
    System.out.println(exitcode);

    inStream = addProc.getInputStream();
    InputStreamReader sr = new InputStreamReader(inStream);
    BufferedReader br = new BufferedReader(sr);

    String line = null;
    int numInsertions = 0;
    while ((line = br.readLine()) != null) {

        String[] p = line.split(" ");
        numInsertions += Integer.parseInt(p[1]);

    }
    br.close();
}
}

Both leftPath and rightPath are File objects pointing to the files to be compared.

+1  A: 

Just a couple of hints, you could:

  • pipe the output of diff directly into grep: diff -n leftpath rightPath | grep "^a"
  • read the output file from grep instead of stdin: grep "^a" tmpFile
  • use ProcessBuilder to get your Process where you can easily avoid a blocking process because you're not reading stderr by using redirectErrorStream
WMR