From b4938059be72908847c803bf61ce9f668378cbfc Mon Sep 17 00:00:00 2001 From: mduigou Date: Mon, 6 May 2013 20:54:54 -0700 Subject: 8003258: BufferedReader.lines() Reviewed-by: alanb, mduigou, psandoz Contributed-by: Brian Goetz , Henry Jen --- src/share/classes/java/io/BufferedReader.java | 69 ++++++++++++++++- .../classes/java/io/UncheckedIOException.java | 90 ++++++++++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/share/classes/java/io/UncheckedIOException.java (limited to 'src/share/classes/java/io') diff --git a/src/share/classes/java/io/BufferedReader.java b/src/share/classes/java/io/BufferedReader.java index 556abb2a40..d742233a0f 100644 --- a/src/share/classes/java/io/BufferedReader.java +++ b/src/share/classes/java/io/BufferedReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,13 @@ package java.io; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + /** * Reads text from a character-input stream, buffering characters so as to * provide for the efficient reading of characters, arrays, and lines. @@ -522,4 +529,64 @@ public class BufferedReader extends Reader { } } } + + /** + * Returns a {@code Stream}, the elements of which are lines read from + * this {@code BufferedReader}. The {@link Stream} is lazily populated, + * i.e, read only occurs during the + * terminal + * stream operation. + * + *

The reader must not be operated on during the execution of the + * terminal stream operation. Otherwise, the result of the terminal stream + * operation is undefined. + * + *

After execution of the terminal stream operation there are no + * guarantees that the reader will be at a specific position from which to + * read the next character or line. + * + *

If an {@link IOException} is thrown when accessing the underlying + * {@code BufferedReader}, it is wrapped in an {@link + * UncheckedIOException} which will be thrown from the {@code Stream} + * method that caused the read to take place. This method will return a + * Stream if invoked on a BufferedReader that is closed. Any operation on + * that stream requires reading from the BufferedReader after is it closed + * will cause an UncheckedIOException to be thrown. + * + * @return a {@code Stream} providing the lines of text + * described by this {@code BufferedReader} + * + * @since 1.8 + */ + public Stream lines() { + Iterator iter = new Iterator() { + String nextLine = null; + + @Override + public boolean hasNext() { + if (nextLine != null) { + return true; + } else { + try { + nextLine = readLine(); + return (nextLine != null); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + } + + @Override + public String next() { + if (nextLine != null || hasNext()) { + String line = nextLine; + nextLine = null; + return line; + } else { + throw new NoSuchElementException(); + } + } + }; + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iter, Spliterator.ORDERED)); + } } diff --git a/src/share/classes/java/io/UncheckedIOException.java b/src/share/classes/java/io/UncheckedIOException.java new file mode 100644 index 0000000000..22c43e3807 --- /dev/null +++ b/src/share/classes/java/io/UncheckedIOException.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.io; + +import java.util.Objects; + +/** + * Wraps an {@link IOException} with an unchecked exception. + * + * @since 1.8 + */ +public class UncheckedIOException extends RuntimeException { + private static final long serialVersionUID = -8134305061645241065L; + + /** + * Constructs an instance of this class. + * + * @param message + * the detail message, can be null + * @param cause + * the {@code IOException} + * + * @throws NullPointerException + * if the cause is {@code null} + */ + public UncheckedIOException(String message, IOException cause) { + super(message, Objects.requireNonNull(cause)); + } + + /** + * Constructs an instance of this class. + * + * @param cause + * the {@code IOException} + * + * @throws NullPointerException + * if the cause is {@code null} + */ + public UncheckedIOException(IOException cause) { + super(Objects.requireNonNull(cause)); + } + + /** + * Returns the cause of this exception. + * + * @return the {@code IOException} which is the cause of this exception. + */ + @Override + public IOException getCause() { + return (IOException) super.getCause(); + } + + /** + * Called to read the object from a stream. + * + * @throws InvalidObjectException + * if the object is invalid or has a cause that is not + * an {@code IOException} + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + Throwable cause = super.getCause(); + if (!(cause instanceof IOException)) + throw new InvalidObjectException("Cause must be an IOException"); + } +} -- cgit v1.2.3