0

I want to transfer the content of a String object from a Java program to a C program as input. To avoid the use of temporarly file I want to use the stdin with process.getOutputStream() as I'm executing the C program with ProcessBuilder via my Java program.

From the shell, my C program is able to work from input gave from the keyboard or with a file given by a redirector:

#myprog < myFile.txt

When I send data from my Java program process.getOutputStream().write() it is working while there is less than 16363bytes to send. If more, an IOException occur with message "Stream closed".

Here my java code:

ProcessBuilder processBuilder;

    if (Double.isNaN(delta2))
    {
        processBuilder = new ProcessBuilder(CMD.getPath(), Integer.toString(algoType.ordinal() + 1));
    }
    else
    {
        processBuilder = new ProcessBuilder(CMD.getPath(), Integer.toString(algoType.ordinal() + 1), Double.toString(delta2));
    }

    try
    {
        Process process = processBuilder.start();

        OutputStream writer = process.getOutputStream();

        InputStream matrixToSend = new ByteArrayInputStream(shortestPathMatrix.getBytes());

        int buf;
        int i = 0;

        if (matrixToSend != null)
        {
            while ((buf = matrixToSend.read()) != -1)
            {
                System.out.println(i++);
                if (i == 8172)
                {
                    writer.flush();
                }

                writer.write(buf);
            }

            System.out.println("plouf");
            writer.close();
        }

        ReadThread stdoutThread = new ReadThread(process.getInputStream());
        ReadThread stderrthread = new ReadThread(process.getErrorStream());

        process.waitFor();

        for (ReadThread t : new ReadThread[]
        { stdoutThread, stderrthread })
        {
            synchronized (t)
            {
                if (!t.hasCompleted)
                {
                    t.wait();
                }
            }
        }

        ProcessOutput output = new ProcessOutput(process.exitValue(), stdoutThread.targetBuffer.toByteArray(), stderrthread.targetBuffer.toByteArray());

        if (output.getReturnCode() == 0)
        {
            writer.close();
            return parseOutoutToResult(new String(output.getStdout()));
        }
        else
        {
            writer.close();
            byte[] out = output.getStdout();
            byte[] err = output.getStderr();
            String error = new String(err.length == 0 ? out : err);
            throw new IllegalStateException("Command " + CMD.getPath() + " [" + Integer.toString(algoType.ordinal() + 1) + " " + Double.toString(delta2) + "] has failed (exit code=" + output.getReturnCode()
                    + ")\n" + error);
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

In my C code, I simply do:

FILE *f = stdin;

And then:

while (fgets(line, MAX_LINE_LENGTH, f))
{
    //process
}

Thanks for any help.

4

2 回答 2

0

Either fgets() does not get executed or assuming MAX_LINE_LENGTHis larger then 16363: As the C source uses fgets() which only returns after having received (an EOF or) a newline (typicall a \n) the Java code shall send a \n before the transmitting pipe is full.

The size of a pipe is system dependened and seems to be 16k on your system.

Also the Java code seems to be sending binary data, where as the C code expects ascii data (as using fgets()). So the Java ought to convert the integers it sends to their ascii format and write() out the latter.

于 2013-10-17T14:30:55.837 回答
0

Thanks all for your help. In fact it was a stupid bug in the way I was formatting the data to be send. The C program was closing the pipe as it was not reconizing the data...

于 2013-10-23T11:27:25.560 回答