RFR JDK-8003258: BufferedReader.lines()

Henry Jen henry.jen at oracle.com
Tue Apr 30 21:36:27 PDT 2013


On 04/29/2013 02:29 AM, Paul Sandoz wrote:
> 
> On Apr 27, 2013, at 10:15 AM, Alan Bateman <Alan.Bateman at oracle.com> wrote:
> 
>> On 26/04/2013 22:59, Henry Jen wrote:
>>> Hi,
>>>
>>> Please review webrev at
>>>
>>> http://cr.openjdk.java.net/~henryjen/ccc/8003258.1/webrev/
>>>
>>> It adds a method to BufferedReader.
>>>
>>> public Stream<String>  lines() {}
>>>
>> I'm not so sure about setting expectations that you can readily mix stream usage with the other methods that BufferedReader defines. This puts a strict requirement on the implementation that it must be based on readLines and that it can never do any read ahead.
>>

I hear you, I think this is a feature. As a BufferedReader, it is
"Buffered", thus any read-ahead should probably happening with the buffer?

It is probably desired to have optimized lines() method elsewhere, for
example, one of such candidate would be Files::lines() although the
initial implementation is based on BufferedReader::lines().


> 
> Even if the implementation uses readLines, if the stream is evaluated in parallel more lines may be read than absolutely necessary so we cannot guarantee that the following will consume at most one element:
> 
>   br.lines().parallel().findAny();
>   br.lines().parallel().findFirst();
>   br.lines().parallel().limit(1).collect(toList());
> 
> So we have to say something like:
> 
>     * <p>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
>     *
>     * <p>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.
> 

Right, this is a general characteristic of stream operation, there is no
guarantee on how many element to be consumed. We do say when mixed API,
it pick up from where it was left though.

What do people think about following spec? Maybe we can remove the
"Since..." for the mix API usage so we don't "set expectation" by
calling it out. Or do you think we should actually remove most of the
text base on the "readLine" implementation?

> 
>     /**
>      * Returns a {@code Stream}, the elements of which are lines read from this
>      * {@code BufferedReader}.  The {@link Stream} is lazily populated via
>      * calls to {@link #readLine()}.
>      *
>      * <p>Each element consumed by the {@code Stream} caused a line to be
>      * read from this {@code BufferedReader}. Since the {@code Stream} does
>      * not necessarily consume all lines, it is possible to mix and use
>      * different read methods on a {@code BufferedReader}. Each method will
>      * simply pick up from where it was left on last read.
>      *
>      * <p>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
>      *
>      * <p>Noted that some terminal stream operations make no guarantee how many
>      * element to be consumed. Therefore 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.
>      *
>      * <p>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. For example, when trying to
>      * read from the {@code Stream} after the {@code BufferedReader} is
>      * closed, will throw an {@code UncheckedIOException}. Note that This
>      * method will return the {@code Stream} even if this {@code
>      * BufferedReader} is closed, but the operation cause reading will throw
>      * {@code UncheckedIOException}.
>      *
>      * @return a {@code Stream<String>} providing the lines of text
>      *         described by this {@code BufferedReader}
>      *
>      * @since 1.8
>      */
>     public Stream<String> lines() {}

Cheers,
Henry


More information about the lambda-dev mailing list