3

I am new with Java programming and i wasn't able to find an answer to my problem anywhere.

How to read few lines of a file and store it in a String (or a list of Strings).

For example from a file of 1000 lines i need to read only 200 lines starting from 200th line to 400th line.

I came across FileInputStream using it we can define the starting position but we cannot define the ending position.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • A side note about your final sentence: As a general rule of thumb, use `InputStream` (e.g. `FileInputStream` for binary (non-text) data, and `Reader` (e.g. `FileReader`) for text data. You'll find the API to be much more cooperative if you do. – Jason C Aug 27 '16 at 18:06
  • The file on disk is not saved by lines, you can't seek to a line as you wish, you need to read through the file, to count lines, then read the lines needed, then stop reading future lines. Cache reading via `BufferedReader` will speed up your application. – Eric Aug 27 '16 at 18:08

1 Answers1

10

You can't do this directly. You can only do this by reading and ignoring the first lines you don't care about.

You can do that with Java's LineNumberReader. Use it to read the file, reading one line at a time. Keep reading and ignoring lines until you get to line 200, start processing the data, stop once you reach 400.

Note: Before you ask, no, LineNumberReader#setLineNumber does not change the file position, it just artificially sets the reported line number:

By default, line numbering begins at 0. This number increments at every line terminator as the data is read, and can be changed with a call to setLineNumber(int). Note however, that setLineNumber(int) does not actually change the current position in the stream; it only changes the value that will be returned by getLineNumber().

Another option is to just use a BufferedReader, calling readLine() 199 times to skip to the 200th lines, then reading the next 200 (or whatever) lines. But, LineNumberReader just conveniently keeps track of the line number for you.

A third option, since Java 8, is to use the streams API and do something like:

Files.lines(Paths.get("input.txt"))
  .skip(200)   // skip to line 200
  .limit(200)  // discard all but the 200 lines following this
  .forEach(...)

Passing your processing Consumer to forEach().

Either way, same concept: You have to read and discard the first N lines of the file, you can't get around that.


Example with LineNumberReader:

LineNumberReader reader = new LineNumberReader(new FileReader("input.txt"));

for (String line = reader.readLine(); line != null; line = reader.readLine()) {
    if (reader.getLineNumber() > 400) {
        break; // we're done
    } else if (reader.getLineNumber() >= 200) {
        // do something with 'line'
    }
}

Example with BufferedReader, not quite as straightforward as the above:

BufferedReader reader = new BufferedReader(new FileReader("input.txt"));

// skip to the 200th line
for (int n = 0; n < 199 && reader.readLine() != null; ++ n)
    ;

// process the next 201 (there's 201 lines between 200 and 400, inclusive)
String line;
for (int n = 0; n < 201 && (line = reader.readLine()) != null; ++ n) {
    // do something with 'line'
}

And an example using Files is already given above.

How you want to organize the conditions and test for EOF and such in your for or while or whatever loops is more a matter of personal taste, those are just arbitrary illustrative examples.

Jason C
  • 38,729
  • 14
  • 126
  • 182
  • Forgot about the stream API. Also I hope my added examples don't conflate anything, let me know if they distract and I'll get rid of them. – Jason C Aug 27 '16 at 18:04
  • 1
    I like the Java 8 solution. +1 LineNumberReader is better solution for java 7 anyday Thanks for the prompt reply! – Manav Veer Gulati Aug 27 '16 at 18:18
  • @ManavVeerGulati Yeah the streams stuff is super cool, I don't get an opportunity to use it a lot because I do a lot of work on legacy platforms and applications constrained to older versions of Java. – Jason C Aug 27 '16 at 18:20
  • Is there a way to not go through all characters in a line just count and skip to the next line. As here we are reading all the characters till we reach that particular line. – Manav Veer Gulati Aug 31 '16 at 10:24
  • @Manav No. How could it know where the line breaks are without reading all of the characters to find them? There isn't an index of where in the file each line starts or anything. – Jason C Aug 31 '16 at 10:45