My plan is to use ByteBuffer
with Apache Common Exec to send output from one command as an input to another command.
I am able to do this using PipedOutputStream
and PipedInputStream
and below is the code which works fine.
public static void testApacheCommons1() throws ExecuteException, IOException {
PipedOutputStream ifOutputStream = new PipedOutputStream();
PipedInputStream ifInputStream = new PipedInputStream();
ifOutputStream.connect(ifInputStream);
String readCommand = "sudo dd bs=1 count=30 if=" + "/dev/sdb1" + " skip=50k";
CommandLine cmdLineForRead = CommandLine.parse(readCommand);
DefaultExecutor executorRead = new DefaultExecutor();
ExecuteStreamHandler executeReadStreamHandler = new PumpStreamHandler(ifOutputStream);
executorRead.setStreamHandler(executeReadStreamHandler);
executorRead.execute(cmdLineForRead, new DefaultExecuteResultHandler());
String writeCommand = "sudo dd bs=1 of=" + "/dev/sdb2"+ " seek=50k";
CommandLine cmdLineForWrite = CommandLine.parse(writeCommand);
DefaultExecutor executorWrite = new DefaultExecutor();
ExecuteStreamHandler executeWriteStreamHandler = new PumpStreamHandler(System.out, System.err, ifInputStream);
executorWrite.setStreamHandler(executeWriteStreamHandler);
executeWriteStreamHandler.start();
executorWrite.execute(cmdLineForWrite, new DefaultExecuteResultHandler());
}
The above code works fine but I want to get the output from the first command, and put it to ByteBuffer
and provide it as the input to the next command.
Below is the code which I am trying to do but it is not working as expected (I am able to see the buffer getting populated but it is not writing to the disk, which was happening in the above code when I used PipedOutputStream
and PipedInputStream
).
In this case I am using ByteBufferBackedOutputStream
and ByteBufferBackedInputStream
which are custom classes and I got the implementation from another post here at SO.
public static void testApacheCommons() throws ExecuteException, IOException {
ByteBuffer byteBuffer = ByteBuffer.allocate(30);
String readCommand = "sudo dd bs=1 count=30 if=" + "/dev/sdb1" + " skip=50k";
CommandLine cmdLineForRead = CommandLine.parse(readCommand);
DefaultExecutor executorRead = new DefaultExecutor();
ExecuteStreamHandler executeReadStreamHandler = new PumpStreamHandler(
new ByteBufferBackedOutputStream(byteBuffer));
executorRead.setStreamHandler(executeReadStreamHandler);
executorRead.execute(cmdLineForRead, new DefaultExecuteResultHandler());
String writeCommand = "sudo dd bs=1 of=" + "/dev/sdb2" + " seek=50k";
CommandLine cmdLineForWrite = CommandLine.parse(writeCommand);
DefaultExecutor executorWrite = new DefaultExecutor();
ExecuteStreamHandler executeWriteStreamHandler = new PumpStreamHandler(System.out, System.err,
new ByteBufferBackedInputStream(byteBuffer));
executorWrite.setStreamHandler(executeWriteStreamHandler);
executorWrite.execute(cmdLineForWrite, new DefaultExecuteResultHandler());
}
public class ByteBufferBackedInputStream extends InputStream {
ByteBuffer buf;
public ByteBufferBackedInputStream(ByteBuffer buf) {
this.buf = buf;
}
public int read() throws IOException {
if (!buf.hasRemaining()) {
return -1;
}
return buf.get() & 0xFF;
}
public int read(byte[] bytes, int off, int len) throws IOException {
if (!buf.hasRemaining()) {
return -1;
}
len = Math.min(len, buf.remaining());
buf.get(bytes, off, len);
return len;
}
}
public class ByteBufferBackedOutputStream extends OutputStream {
ByteBuffer buf;
public ByteBufferBackedOutputStream(ByteBuffer buf) {
this.buf = buf;
}
public void write(int b) throws IOException {
buf.put((byte) b);
}
public void write(byte[] bytes, int off, int len) throws IOException {
buf.put(bytes, off, len);
}
}
Okay so the issue was that the position
for the bytebuffer
was at the last location so when the write happened it didn't find the elements saved within the buffer.
By trail and error and going through all the functions I came to know about buffer.rewind()
Buffer java.nio.Buffer.rewind() Rewinds this buffer. The position is set to zero and the mark is discarded.
so after the read from the disk just ran buffer.rewind()
and I was able to see the values written to disk.