code: public static long stream(InputStream input, OutputStream output, int bufferSize) throws IOException {
          try (ReadableByteChannel inputChannel = Channels.newChannel(input);
                  WritableByteChannel outputChannel = Channels.newChannel(output)) {
              ByteBuffer buffer = ByteBuffer.allocateDirect(bufferSize);
              long size = 0;
  
              while (inputChannel.read(buffer) != -1) {
                  buffer.flip();
                  size += outputChannel.write(buffer);
                  buffer.clear();
              }
  
              return size;
          }
      }
docs: Stream the given input to the given output via NIO {@link Channels} and a
  directly allocated NIO {@link ByteBuffer}. Both the input and output
  streams will implicitly be closed after streaming, regardless of whether
  an exception is been thrown or not.
  
  @param input The input stream.
  @param output The output stream.
  @param bufferSize
  @return The length of the written bytes.
  @throws IOException When an I/O error occurs.