Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added lines() in LineReader #6308

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions guava-tests/test/com/google/common/io/LineBufferTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.google.common.io;

import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import java.io.BufferedReader;
Expand All @@ -26,6 +28,7 @@
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
* Unit tests for {@link LineBuffer} and {@link LineReader}.
Expand Down Expand Up @@ -74,6 +77,13 @@ public String apply(String value) {
assertEquals(expectRead, readUsingJava(input, chunk));
assertEquals(expectRead, readUsingReader(input, chunk, true));
assertEquals(expectRead, readUsingReader(input, chunk, false));
try (Stream<String> linesStream = readUsingReaderGetLineReader(input, chunk, true).lines()) {
assertTrue(expectRead.containsAll(linesStream.collect(toImmutableList())));
}

try (Stream<String> linesStream = readUsingReaderGetLineReader(input, chunk, false).lines()) {
assertTrue(expectRead.containsAll(linesStream.collect(toImmutableList())));
}
}
}

Expand Down Expand Up @@ -121,6 +131,12 @@ private static List<String> readUsingReader(String input, int chunk, boolean asR
return lines;
}

private static LineReader readUsingReaderGetLineReader(String input, int chunk, boolean asReader) {
Readable readable =
asReader ? getChunkedReader(input, chunk) : getChunkedReadable(input, chunk);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When looking through the code base, this is the way they split the ternary operator

Suggested change
asReader ? getChunkedReader(input, chunk) : getChunkedReadable(input, chunk);
Readable readable = asReader
? getChunkedReader(input, chunk)
: getChunkedReadable(input, chunk);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I referred this function readUsingReader.

return new LineReader(readable);
}

// Returns a Readable that is *not* a Reader.
private static Readable getChunkedReadable(String input, int chunk) {
final Reader reader = getChunkedReader(input, chunk);
Expand Down
56 changes: 56 additions & 0 deletions guava/src/com/google/common/io/LineReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.AbstractIterator;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.MustBeClosed;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.UncheckedIOException;
import java.nio.CharBuffer;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import javax.annotation.CheckForNull;

/**
Expand Down Expand Up @@ -84,4 +94,50 @@ public String readLine() throws IOException {
}
return lines.poll();
}

/**
* Returns a {@code Stream}, the elements of which are lines read from this {@code LineReader}.
*
* <p>The returned stream is lazy and only reads from the source in the terminal operation. If an
* I/O error occurs while the stream is reading from the source or when the stream is closed, an
* {@link UncheckedIOException} is thrown.
*
* <p>Like {@link LineReader#readLine()}, this method reads a line of text. A line is
* considered to be terminated by any one of a line feed ({@code '\n'}), a carriage return
* ({@code '\r'}), or a carriage return followed immediately by a linefeed ({@code "\r\n"}).
*
* <p>The caller is responsible for ensuring that the returned stream is closed. For example:
*
* <pre>{@code
* try (Stream<String> lines = source.lines()) {
* lines.map(...)
* .filter(...)
* .forEach(...);
* }
* }</pre>
*
* @return a {@code Stream<String>} providing the lines of text
* described by this {@code LineReader}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the JavaDoc should:

  • state that the caller is in charge of closing the Stream (probably also annotate the method with @MustBeClosed)
  • mention the fact that we throw UncheckedIOException
  • explain how we define a line (maybe just mention that a line has the same semantics as in LineReader#lines)

* @throws UncheckedIOException if an I/O error occurs.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method itself does not throw UncheckedIOException right?

*/
@MustBeClosed
public Stream<String> lines() {
AbstractIterator<String> iterator = new AbstractIterator<String>() {
@CheckForNull
@Override
protected String computeNext() {
try {
String next = readLine();
if (next != null) {
return next;
}
return endOfData();
} catch (IOException exception) {
throw new UncheckedIOException(exception);
}
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iterator, Spliterator.ORDERED | Spliterator.NONNULL), false);
}
}