android/guava/src/com/google/common/io/CharStreams.java
@CanIgnoreReturnValue
  static long copyReaderToWriter(Reader from, Writer to) throws IOException {
    checkNotNull(from);
    checkNotNull(to);
    char[] buf = new char[DEFAULT_BUF_SIZE];
    int nRead;
    long total = 0;
    while ((nRead = from.read(buf)) != -1) {
      to.write(buf, 0, nRead);
      total += nRead;
    }
    return total;
  }
@CanIgnoreReturnValue
  static long copyReaderToWriter(Reader from, Writer to) throws IOException {
    checkNotNull(from);
    checkNotNull(to);
    char[] buf = new char[DEFAULT_BUF_SIZE];
    int nRead;
    long total = 0;
    while ((nRead = from.read(buf)) != -1) {
      to.write(buf, 0, nRead);
      total += nRead;
    }
    return total;
  }
Copies all characters between the {@link Reader} and {@link Writer} objects. Does not close or
flush the reader or writer.

<p>This is identical to {@link #copy(Readable, Appendable)} but optimized for these specific
types. CharBuffer has poor performance when being written into or read out of so round tripping
all the bytes through the buffer takes a long time. With these specialized types we can just
use a char array.

@param from the object to read from
@param to the object to write to
@return the number of characters copied
@throws IOException if an I/O error occurs