Add ReversedLinesFileReader.readLines(int).
MODIFY
src/changes/changes.xml
src/changes/changes.xml
@@ -92,6 +92,9 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="ggregory" type="add" due-to="Gary Gregory">
Null-guard IOUtils.close(Closeable, IOConsumer).
</action>
+ <action dev="ggregory" type="add" due-to="Gary Gregory">
+ Add ReversedLinesFileReader.readLines(int).
+ </action>
<action dev="ggregory" type="fix" due-to="Gary Gregory">
Replace FindBugs with SpotBugs.
</action>

MODIFY
src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java
src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
@@ -251,6 +254,35 @@ public String readLine() throws IOException {
return line;
}
+ /**
+ * Returns {@code lineCount} lines of the file from bottom to top.
+ * <p>
+ * If there are less than {@code lineCount} lines in the file, then that's what you get.
+ * </p>
+ * <p>
+ * Note: You can easily flip the result with {@link Collections#reverse(List)}.
+ * </p>
+ *
+ * @param lineCount How many lines to read.
+ * @return A new list
+ * @throws IOException if an I/O error occurs
+ * @since 2.8.0
+ */
+ public List<String> readLines(int lineCount) throws IOException {
+ if (lineCount < 0) {
+ throw new IllegalArgumentException("lineCount < 0");
+ }
+ final ArrayList<String> arrayList = new ArrayList<>(lineCount);
+ for (int i = 0; i < lineCount; i++) {
+ final String line = readLine();
+ if (line == null) {
+ return arrayList;
+ }
+ arrayList.add(line);
+ }
+ return arrayList;
+ }
+
/**
* Closes underlying resources.
*

MODIFY
src/test/java/org/apache/commons/io/input/ReversedLinesFileReaderTestSimple.java
src/test/java/org/apache/commons/io/input/ReversedLinesFileReaderTestSimple.java
import static org.apache.commons.io.input.ReversedLinesFileReaderTestParamBlockSize.assertEqualsAndNoLineBreaks;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
+import java.util.List;
import org.apache.commons.io.IOUtils;
-import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
-
public class ReversedLinesFileReaderTestSimple {
- private ReversedLinesFileReader reversedLinesFileReader;
-
- @AfterEach
- public void closeReader() {
- try {
- reversedLinesFileReader.close();
- } catch(final Exception e) {
- // ignore
- }
- }
-
@Test
public void testFileSizeIsExactMultipleOfBlockSize() throws URISyntaxException, IOException {
final int blockSize = 10;
final File testFile20Bytes = new File(this.getClass().getResource("/test-file-20byteslength.bin").toURI());
- reversedLinesFileReader = new ReversedLinesFileReader(testFile20Bytes, blockSize, "ISO-8859-1");
+ try (ReversedLinesFileReader reversedLinesFileReader = new ReversedLinesFileReader(testFile20Bytes, blockSize,
+ "ISO-8859-1")) {
assertEqualsAndNoLineBreaks("987654321", reversedLinesFileReader.readLine());
assertEqualsAndNoLineBreaks("123456789", reversedLinesFileReader.readLine());
}
+ }
+
+ @Test
+ public void testLineCount() throws URISyntaxException, IOException {
+ final int blockSize = 10;
+ final File testFile20Bytes = new File(this.getClass().getResource("/test-file-20byteslength.bin").toURI());
+ try (ReversedLinesFileReader reversedLinesFileReader = new ReversedLinesFileReader(testFile20Bytes, blockSize,
+ "ISO-8859-1")) {
+ assertThrows(IllegalArgumentException.class, () -> reversedLinesFileReader.readLines(-1));
+ assertTrue(reversedLinesFileReader.readLines(0).isEmpty());
+ final List<String> lines = reversedLinesFileReader.readLines(2);
+ assertEqualsAndNoLineBreaks("987654321", lines.get(0));
+ assertEqualsAndNoLineBreaks("123456789", lines.get(1));
+ assertTrue(reversedLinesFileReader.readLines(0).isEmpty());
+ assertTrue(reversedLinesFileReader.readLines(10000).isEmpty());
+ }
+ }
@Test
public void testUnsupportedEncodingUTF16() throws URISyntaxException {
@@ -65,6 +72,4 @@ public void testUnsupportedEncodingBig5() throws URISyntaxException {
() -> new ReversedLinesFileReader(testFileEncodingBig5, IOUtils.DEFAULT_BUFFER_SIZE, "Big5").close());
}
-
-
}

Add ReversedLinesFileReader.readLines(int).