This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I'm reading a file using LineNumberReader api.
But it reads file from starting of the file. I have a line number with me, I have to read file, from that location.
Is there any api in java that will goto given line number ?
Just use an empty "for" loop and read all the lines that come before the one you want to start with -- and then start reading the lines that count. There's no other way to do it -- if there were a library routine to do this, it would have to do the same thing.
To expand on that a bit: you will need to read all the preceding lines, at least once. If you will need to read the same file more than once, starting from different locations each time, then you may want to build a List<String> that contains all the lines in the file. Then you can easily refer to any line by index. Of course if the fule is too huge to fit in memory all at once, this won't work. Or if you're only going to read the file once, period, then this isn't worth the trouble. But it's often a useful technique nonetheless.
author and iconoclast
Coming back to this, after reading Mike's reply, I should add that in fact a library routine to skip to a particular line number could be more efficient than this. It could find the line endings, one at a time, but not actually create the Strings representing the lines. This might make sense if you have to skip many lines in many big files. And indeed, if you had to skip to many different lines in one big file, you might keep just a list of the line offsets, and use RandomAccessFile.seek() to start reading from the offset for a given line. But that's all overkill for many applications.
Joined: Mar 05, 2008
An early Java job I had was was on something even more elaborate. We had a huge text file that an application needed to be able to access by line number as quickly as possible. The file was far too big to fit into memory. Instead we built an index - find what byte each line began on, and remember that start position, so that when you needed a particular line, you could quickly build a FileInputStream and skip to the desired location.
(In those days, JDK 1.2, RandomAccessFile turned out to be horribly inefficient compared to FileInputStream. That difference went away in JDK 1.3, fortunately.)
But! -- it turned out that even the index was too big to fit in memory on some of the machines the application was expected to run on. So we ended up indexing every N lines, where N was configurable. Say N = 100, you'd build an index of the start location of every 100th line. Then when you need to read line 42378, you find the location of line 42300, make a FileInputStream, skip to that location, scan past the next 78 line breaks, and then read line 42378.
A further elaboration was, on the next read, check if it was a request for something earlier in the file, or something later. If it was something later, we could re-use the FIS without building a new one. The benefit of this enhancement can be described as minor at best.
The biggest problem was when we started looking at files with different encodings - often within the same file (!). Counting how many bytes had been used by a particular line turned out to be the hardest part of that project.