I have an input开发者_开发技巧 byte array which I would like to feed to the standard input of an external program (Process
). Also, I would like to collect the output in a byte array.
What is the most elegant way to do this? PipedInputStream
/PipedOutputStream
? nio.channels.Pipe
?
Sample code would be a plus because I can't really figure out how to do this in a good way...
Pipes are for use between threads in Java. They aren't part of this solution. To write the byte array to the Process, just call Process.getOutputStream.write(byte[]), as often as necessary. To read it into a byte array, just call Process.getInputStream.read(byte[]). If you don't know how much output there will be, copy it into a ByteArrayOutputStream.
Combining PipedInputStream
with PipedOutputStream
and Peter's MultiOutputStream
from another post here, you can get the following:
final int CAPCITY = 4096;
final int PIPE_SIZE = 4096;
PipedOutputStream pout = new PipedOutputStream();
ByteArrayOutputStream bout = new ByteArrayOutputStream(CAPACITY);
MultiOutputStream multiOs= new MultiOutputStream(pout, bout);
PipedInputStream is = new PipedInputStream(pout, PIPE_SIZE);
Now, if you execute:
byte[] bytes = new bytes[1024];
multiOs.write(bytes, 0, 1024);
You feed your PipedInputStream
, optionally handing the reference over to another process, i.e. Java Thread. Simultaneoulsy, you write into a byte array, which can be queried by:
bytes[] written = bout.toByteArray();
How about an OutputStream which copies the data. You can attach any number of OutputStreams including ByteArrayOutputStream to this. The first write isn't required except for efficiency.
public class MultiOutputStream extends OutputStream {
private final OutputStream[] outs;
public MultiOutputStream(OutputStream... outs) {
this.outs = outs;
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
for (OutputStream out : outs)
out.write(b, off, len);
}
@Override
public void write(int b) throws IOException {
for (OutputStream out : outs)
out.write(b);
}
}
精彩评论