Skip to content

Commit a6af211

Browse files
author
Gary Gregory
committed
Add ReversedLinesFileReader.readLines(int).
1 parent acda845 commit a6af211

3 files changed

Lines changed: 59 additions & 19 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ The <action> type attribute can be add,update,fix,remove.
9292
<action dev="ggregory" type="add" due-to="Gary Gregory">
9393
Null-guard IOUtils.close(Closeable, IOConsumer).
9494
</action>
95+
<action dev="ggregory" type="add" due-to="Gary Gregory">
96+
Add ReversedLinesFileReader.readLines(int).
97+
</action>
9598
<action dev="ggregory" type="fix" due-to="Gary Gregory">
9699
Replace FindBugs with SpotBugs.
97100
</action>

src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import java.nio.file.Files;
2929
import java.nio.file.Path;
3030
import java.nio.file.StandardOpenOption;
31+
import java.util.ArrayList;
32+
import java.util.Collections;
33+
import java.util.List;
3134

3235
import org.apache.commons.io.Charsets;
3336
import org.apache.commons.io.IOUtils;
@@ -225,7 +228,7 @@ public ReversedLinesFileReader(final Path file, final int blockSize, final Strin
225228

226229
/**
227230
* Returns the lines of the file from bottom to top.
228-
*
231+
*
229232
* @return the next line or null if the start of the file is reached
230233
* @throws IOException if an I/O error occurs
231234
*/
@@ -251,6 +254,35 @@ public String readLine() throws IOException {
251254
return line;
252255
}
253256

257+
/**
258+
* Returns {@code lineCount} lines of the file from bottom to top.
259+
* <p>
260+
* If there are less than {@code lineCount} lines in the file, then that's what you get.
261+
* </p>
262+
* <p>
263+
* Note: You can easily flip the result with {@link Collections#reverse(List)}.
264+
* </p>
265+
*
266+
* @param lineCount How many lines to read.
267+
* @return A new list
268+
* @throws IOException if an I/O error occurs
269+
* @since 2.8.0
270+
*/
271+
public List<String> readLines(int lineCount) throws IOException {
272+
if (lineCount < 0) {
273+
throw new IllegalArgumentException("lineCount < 0");
274+
}
275+
final ArrayList<String> arrayList = new ArrayList<>(lineCount);
276+
for (int i = 0; i < lineCount; i++) {
277+
final String line = readLine();
278+
if (line == null) {
279+
return arrayList;
280+
}
281+
arrayList.add(line);
282+
}
283+
return arrayList;
284+
}
285+
254286
/**
255287
* Closes underlying resources.
256288
*

src/test/java/org/apache/commons/io/input/ReversedLinesFileReaderTestSimple.java

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,53 +18,58 @@
1818

1919
import static org.apache.commons.io.input.ReversedLinesFileReaderTestParamBlockSize.assertEqualsAndNoLineBreaks;
2020
import static org.junit.jupiter.api.Assertions.assertThrows;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
2122

2223
import java.io.File;
2324
import java.io.IOException;
2425
import java.io.UnsupportedEncodingException;
2526
import java.net.URISyntaxException;
27+
import java.util.List;
2628

2729
import org.apache.commons.io.IOUtils;
28-
import org.junit.jupiter.api.AfterEach;
2930
import org.junit.jupiter.api.Test;
3031

31-
3232
public class ReversedLinesFileReaderTestSimple {
3333

34-
private ReversedLinesFileReader reversedLinesFileReader;
35-
36-
@AfterEach
37-
public void closeReader() {
38-
try {
39-
reversedLinesFileReader.close();
40-
} catch(final Exception e) {
41-
// ignore
34+
@Test
35+
public void testFileSizeIsExactMultipleOfBlockSize() throws URISyntaxException, IOException {
36+
final int blockSize = 10;
37+
final File testFile20Bytes = new File(this.getClass().getResource("/test-file-20byteslength.bin").toURI());
38+
try (ReversedLinesFileReader reversedLinesFileReader = new ReversedLinesFileReader(testFile20Bytes, blockSize,
39+
"ISO-8859-1")) {
40+
assertEqualsAndNoLineBreaks("987654321", reversedLinesFileReader.readLine());
41+
assertEqualsAndNoLineBreaks("123456789", reversedLinesFileReader.readLine());
4242
}
4343
}
4444

4545
@Test
46-
public void testFileSizeIsExactMultipleOfBlockSize() throws URISyntaxException, IOException {
46+
public void testLineCount() throws URISyntaxException, IOException {
4747
final int blockSize = 10;
4848
final File testFile20Bytes = new File(this.getClass().getResource("/test-file-20byteslength.bin").toURI());
49-
reversedLinesFileReader = new ReversedLinesFileReader(testFile20Bytes, blockSize, "ISO-8859-1");
50-
assertEqualsAndNoLineBreaks("987654321", reversedLinesFileReader.readLine());
51-
assertEqualsAndNoLineBreaks("123456789", reversedLinesFileReader.readLine());
49+
try (ReversedLinesFileReader reversedLinesFileReader = new ReversedLinesFileReader(testFile20Bytes, blockSize,
50+
"ISO-8859-1")) {
51+
assertThrows(IllegalArgumentException.class, () -> reversedLinesFileReader.readLines(-1));
52+
assertTrue(reversedLinesFileReader.readLines(0).isEmpty());
53+
final List<String> lines = reversedLinesFileReader.readLines(2);
54+
assertEqualsAndNoLineBreaks("987654321", lines.get(0));
55+
assertEqualsAndNoLineBreaks("123456789", lines.get(1));
56+
assertTrue(reversedLinesFileReader.readLines(0).isEmpty());
57+
assertTrue(reversedLinesFileReader.readLines(10000).isEmpty());
58+
}
5259
}
5360

5461
@Test
5562
public void testUnsupportedEncodingUTF16() throws URISyntaxException {
5663
final File testFileEmpty = new File(this.getClass().getResource("/test-file-empty.bin").toURI());
5764
assertThrows(UnsupportedEncodingException.class,
58-
() -> new ReversedLinesFileReader(testFileEmpty, IOUtils.DEFAULT_BUFFER_SIZE, "UTF-16").close());
65+
() -> new ReversedLinesFileReader(testFileEmpty, IOUtils.DEFAULT_BUFFER_SIZE, "UTF-16").close());
5966
}
6067

6168
@Test
6269
public void testUnsupportedEncodingBig5() throws URISyntaxException {
6370
final File testFileEncodingBig5 = new File(this.getClass().getResource("/test-file-empty.bin").toURI());
6471
assertThrows(UnsupportedEncodingException.class,
65-
() -> new ReversedLinesFileReader(testFileEncodingBig5, IOUtils.DEFAULT_BUFFER_SIZE, "Big5").close());
72+
() -> new ReversedLinesFileReader(testFileEncodingBig5, IOUtils.DEFAULT_BUFFER_SIZE, "Big5").close());
6673
}
6774

68-
69-
7075
}

0 commit comments

Comments
 (0)