我的计划是使用ByteBuffer
Apache Common Exec将一个命令的输出作为输入发送到另一个命令。
我可以使用PipedOutputStream
and来做到这一点PipedInputStream
,下面是可以正常工作的代码。
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());
}
上面的代码工作正常,但我想从第一个命令中获取输出,并将其放入ByteBuffer
并提供它作为下一个命令的输入。
下面是我正在尝试执行的代码,但它没有按预期工作(我能够看到缓冲区被填充,但它没有写入磁盘,当我使用PipedOutputStream
and时发生在上面的代码中PipedInputStream
)。
在这种情况下,我使用ByteBufferBackedOutputStream
的ByteBufferBackedInputStream
是自定义类,我从 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);
}
}