views:

469

answers:

2

I have a log file which gets updated every second. I need to read the log file periodically, and once I do a read, I need to store the file pointer position at the end of the last line I read and in the next periodic read I should start from that point.

Currently, I am using a random access file in Java and using the getFilePointer() method to get he offset value and the seek() method to go to the offset position.

However, I have read in most articles and even the Java doc recommendations to use BufferredReader for efficient reading of a file. How can I achieve this (getting the filepointer and moving to the last line) using a BufferedReader, or is there any other efficient way to achieve this task?

+3  A: 

A couple of ways that should work:

  • open the file using a FileInputStream, skip() the relevant number of bytes, then wrap the BufferedReader around the stream (via an InputStreamReader);
  • open the file (with either FileInputStream or RandomAccessFile), call getChannel() on the stream/RandomAccessFile to get an underlying FileChannel, call position() on the channel, then call Channels.newInputStream() to get an input stream from the channel, which you can pass to InputStreamReader -> BufferedReader.

I haven't honestly profiled these to see which is better performance-wise, but you should see which works better in your situation.

The problem with RandomAccessFile is essentially that its readLine() method is very inefficient. If it's convenient for you to read from the RAF and do your own buffering to split the lines, then there's nothing wrong with RAF per se-- just that its readLine() is poorly implemented

Neil Coffey
A: 

I have a similar problem, and I see one problem:

When using solution 1, you cannot get the byte position because the wrapping BufferedReader does not provide any getFilePointer-like function. On the other side, the underlaying Reader and Stream do not have the same position because the data is buffered.

The other solution is no option for me, because I need to index the whole file first (and fast) and in a second stept I want to seek and read.

Indexing the file (10MB) with a RandomAccessFile is 15s, Indexing with BufferedReader is 2.5s. But as said:BufferedReader does not return any position and accumulating the string length causes problem because of line termination characters and/or charset problems(multibyte).

Daniel