尝试将 Apache Common exec 与 bytebuffer 一起使用以将输出从一个命令推送到 java 中的另一个命令

Trying to use Apache Common exec with bytebuffer to push output from one command to another command in java

我的计划是使用 ByteBufferApache Common Exec 将一个命令的输出作为输入发送到另一个命令。

我可以使用 PipedOutputStreamPipedInputStream 来做到这一点,下面是工作正常的代码。

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 并将其作为下一个命令的输入提供。

下面是我正在尝试执行的代码,但它没有按预期工作(我能够看到缓冲区被填充但它没有写入磁盘,当我在上面的代码中发生这种情况时使用 PipedOutputStreamPipedInputStream).

在这种情况下,我使用的是 ByteBufferBackedOutputStreamByteBufferBackedInputStream,它们是自定义的 类,我在 SO 处从另一个 post 那里获得了实现。

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);
    }

}

好的,所以问题是 bytebufferposition 位于最后一个位置,因此当写入发生时,它没有找到缓冲区中保存的元素。 通过反复试验并遍历我开始了解的所有功能 buffer.rewind()

Buffer java.nio.Buffer.rewind() 
Rewinds this buffer. The position is set to zero and the mark is discarded.

所以在从磁盘读取 运行 buffer.rewind() 之后,我能够看到写入磁盘的值。