@Override
    public ClickHouseOutputStream writeBytes(byte[] bytes, int offset, int length) throws IOException {
        if (bytes == null) {
            throw new NullPointerException();
        } else if (offset < 0 || length < 0 || length > bytes.length - offset) {
            throw new IndexOutOfBoundsException();
        } else if (length == 0) {
            return this;
        }
        ensureOpen();

        ByteBuffer b = buffer;
        while (length > 0) {
            int remain = b.remaining();
            if (length < remain) {
                b.put(bytes, offset, length);
                length = 0;
            } else if (b.position() == 0 && length >= b.remaining()) {
                // if the length is bigger than
                // allocate with correct buffer size bufferSize
                b.put(bytes, offset, remain);
                offset += remain;
                length -= remain;
                updateBuffer(true);
                b = buffer;
            } else {
                b.put(bytes, offset, remain);
                offset += remain;
                length -= remain;
                updateBuffer(true);
                b = buffer;
            }
        }

        return this;
    }
A combination of {@link java.io.PipedOutputStream} and
{@link java.io.PipedInputStream} for streaming data between server and
client. To avoid dead lock and high memory usage, please make sure writer and
reader are on two separate threads.
clickhouse-data/src/main/java/com/clickhouse/data/stream/BlockingPipedOutputStream.java