Any better way to copy from Readable to OutputStream? I neglected java.nio package in the past and now I am wondering if this is the best way to copy everything from a Readable to an OutputStream:

public static void copy(@Nonnull Readable src, @WillNotClose @Nonnull OutputStream dest, @Nullable Charset targetCharset) throws IOException {
    targetCharset = safeCharset(targetCharset);
    CharBuffer buf = CharBuffer.allocate(CHAR_BUF_SIZE);
    ByteBuffer byteBuffer = null;
    WritableByteChannel outChannel = Channels.newChannel(dest);

    while (src.read(buf) != -1) {
      buf.flip();
      byteBuffer = targetCharset.encode(buf);
      outChannel.write(byteBuffer);
      buf.clear();
    }
}


General

Is this the best way to do it? Am I missing something? What should I do to improve this code?

Closing the channel or not

I wonder if I must/should close the channel created by Channels.newChannel(dest)?
From the general contract of my class the caller of this method here is responsible for closing the provided OutputStream, because every resource should be closed where it was created. It's bad that closing the channel also closes the underlying stream, too. 

On the other hand not closing the channel relies on undocumented implementation details of Channels$WritableByteChannelImpl where calling close() is just a delegate to the underlying stream and setting a close flag.

I do not want to break my general contract and I do not want to rely on undocumented implementation details.

The third option is most probably the best and addressing the source of the problem: 
Write the content directly to the OutputStream without using a channel or any other wrapper around it which must be closed then. But I could not figure out how to achieve this.
Well, last night I came up with that. I am pretty satisfied with it right now but would be happy to see if I am still missing something.

This solution does not rely on implementation details any more and provided streams are left open as the general contract demands it.   

public static void copy(@Nonnull Readable src, @Nonnull @WillNotClose OutputStream dest, @Nullable Charset destCharset) throws IOException {
    CharBuffer charBuf = CharBuffer.allocate(CHAR_BUF_SIZE);

    while (src.read(charBuf) != -1) {
      charBuf.flip();
      copy(charBuf, dest, destCharset);
      charBuf.clear();
    }
}


public static void copy(@Nonnull CharBuffer src, @Nonnull @WillNotClose OutputStream dest, @Nullable Charset destCharset) throws IOException {
    copy(safeCharset(destCharset).encode(src), dest);
}


public static void copy(@Nonnull ByteBuffer src, @Nonnull @WillNotClose OutputStream dest) throws IOException {
    int len = src.remaining();
    int totalWritten = 0;
    byte[] buf = new byte[0];

    while (totalWritten &lt; len) {
        int bytesToWrite = Math.min((len - totalWritten), BYTE_BUF_SIZE);

        if (buf.length &lt; bytesToWrite) {
            buf = new byte[bytesToWrite];
        }

        src.get(buf, 0, bytesToWrite);
        dest.write(buf, 0, bytesToWrite);
        totalWritten += bytesToWrite;
    }
}