android/guava/src/com/google/common/io/CharSource.java
@Beta
  public long length() throws IOException {
    Optional<Long> lengthIfKnown = lengthIfKnown();
    if (lengthIfKnown.isPresent()) {
      return lengthIfKnown.get();
    }

    Closer closer = Closer.create();
    try {
      Reader reader = closer.register(openStream());
      return countBySkipping(reader);
    } catch (Throwable e) {
      throw closer.rethrow(e);
    } finally {
      closer.close();
    }
  }
@Beta
  public long length() throws IOException {
    Optional<Long> lengthIfKnown = lengthIfKnown();
    if (lengthIfKnown.isPresent()) {
      return lengthIfKnown.get();
    }

    Closer closer = Closer.create();
    try {
      Reader reader = closer.register(openStream());
      return countBySkipping(reader);
    } catch (Throwable e) {
      throw closer.rethrow(e);
    } finally {
      closer.close();
    }
  }
Returns the length of this source in chars, even if doing so requires opening and traversing an
entire stream. To avoid a potentially expensive operation, see {@link #lengthIfKnown}.

<p>The default implementation calls {@link #lengthIfKnown} and returns the value if present. If
absent, it will fall back to a heavyweight operation that will open a stream, {@link
Reader#skip(long) skip} to the end of the stream, and return the total number of chars that
were skipped.

<p>Note that for sources that implement {@link #lengthIfKnown} to provide a more efficient
implementation, it is <i>possible</i> that this method will return a different number of chars
than would be returned by reading all of the chars.

<p>In either case, for mutable sources such as files, a subsequent read may return a different
number of chars if the contents are changed.

@throws IOException if an I/O error occurs while reading the length of this source
@since 19.0