/** * Creates a new instance that will read lines from the given * {@code Readable} object. */ public LineReader(Readable readable) { this.readable = checkNotNull(readable); this.reader = (readable instanceof Reader) ? (Reader) readable : null; }
/** * Creates a new writer that appends everything it writes to {@code target}. * * @param target target to which to append output */ AppendableWriter(Appendable target) { this.target = checkNotNull(target); }
@Override public Writer append(CharSequence csq) { checkNotNull(csq); return this; }
@Override public void write(char[] cbuf) { checkNotNull(cbuf); }
@Override public void write(String str) { checkNotNull(str); }
static Reader asReader(final Readable readable) { checkNotNull(readable); if (readable instanceof Reader) { return (Reader) readable; } return new Reader() { @Override public int read(char[] cbuf, int off, int len) throws IOException { return read(CharBuffer.wrap(cbuf, off, len)); } @Override public int read(CharBuffer target) throws IOException { return readable.read(target); } @Override public void close() throws IOException { if (readable instanceof Closeable) { ((Closeable) readable).close(); } } }; } }
/** * Discards {@code n} characters of data from the reader. This method * will block until the full amount has been skipped. Does not close the * reader. * * @param reader the reader to read from * @param n the number of characters to skip * @throws EOFException if this stream reaches the end before skipping all * the characters * @throws IOException if an I/O error occurs */ public static void skipFully(Reader reader, long n) throws IOException { checkNotNull(reader); while (n > 0) { long amt = reader.skip(n); if (amt == 0) { // force a blocking read if (reader.read() == -1) { throw new EOFException(); } n--; } else { n -= amt; } } }
/** * Copies all characters between the {@link Readable} and {@link Appendable} * objects. Does not close or flush either object. * * @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 */ public static long copy(Readable from, Appendable to) throws IOException { Assert.checkNotNull(from); checkNotNull(to); CharBuffer buf = CharBuffer.allocate(BUF_SIZE); long total = 0; while (from.read(buf) != -1) { buf.flip(); to.append(buf); total += buf.remaining(); buf.clear(); } return total; }
/** * Propagates {@code throwable} as-is if it is an instance of * {@link RuntimeException} or {@link Error}, or else as a last resort, * wraps it in a {@code RuntimeException} then propagates. * <p> * This method always throws an exception. The {@code RuntimeException} * return type is only for client code to make Java type system happy in * case a return value is required by the enclosing method. Example usage: * * <pre> * T doSomething() { * try { * return someMethodThatCouldThrowAnything(); * } catch (IKnowWhatToDoWithThisException e) { * return handle(e); * } catch (Throwable t) { * throw Throwables.propagate(t); * } * } * </pre> * * @param throwable * the Throwable to propagate * @return nothing will ever be returned; this return type is only for your * convenience, as illustrated in the example above */ public static RuntimeException propagate(Throwable throwable) { propagateIfPossible(Assert.checkNotNull(throwable)); throw new RuntimeException(throwable); }
/** * Streams lines from a {@link Readable} object, stopping when the processor * returns {@code false} or all lines have been read and returning the result * produced by the processor. Does not close {@code readable}. Note that this * method may not fully consume the contents of {@code readable} if the * processor stops processing early. * * @throws IOException if an I/O error occurs * @since 14.0 */ public static <T> T readLines( Readable readable, LineProcessor<T> processor) throws IOException { checkNotNull(readable); checkNotNull(processor); LineReader lineReader = new LineReader(readable); String line; while ((line = lineReader.readLine()) != null) { if (!processor.processLine(line)) { break; } } return processor.getResult(); }