1

Does readLine() Java function used with BufferedReader cause one disk I/O per call?

If yes, is there any way to read specific number of lines, say n, from a text file causing only one disk I/O?

Here's the code:

String file;
BufferedReader br = new BufferedReader (new FileReader (file));
int n = 10;
for (int i = 0; i < n; i++)
{
    String line = br.readLine ();
    /* Do something */
}
  • Some (all, nowadays?) Operating Systems detect sequential reads, and arrange for asynchronous read-ahead, so that the data is already in memory when your program needs it. – Ingo Mar 12 '13 at 19:01
  • @Ingo: while that's true, the last time I profiled it the process of getting data from the OS buffers and into a Java program was slow enough that using a BufferedReader or BufferedInputStream offered significant performance improvements even when data was being read directly from OS cache. – Jules Mar 13 '13 at 9:16
  • @Jules This is, of course true, and one could regard the data transfer between different address spaces as IO operation. I just wanted to point out another reason why the number of actual disk accesses is not necessarily correlated with the readLine() calls. – Ingo Mar 13 '13 at 9:21
7

It depends on how big your lines are.

By default, BufferedReader uses an 8k buffer (see source). This means that it will attempt to read 8K at a time from the Readerthat it was constructed around. You can read as many lines as will fit into that 8K buffer, without going back to the underlying Reader.


Edit: As a general comment, do not use FileReader. Instead, wrap FileInputStream with an InputStreamReader, and specify your encoding.

  • parsifal: I didn't know how to add code in a comment, so edited the question with code. Now, as per the added code, how many disk reads will it cause, one for each line read (total 10) or only one in total? – high5 Mar 12 '13 at 18:51
  • 1
    @high5 - As I said, it depends on how big your lines are. If your lines are 10k apiece, it will make multiple calls to the FileReader for each line. If your lines are 10 bytes apiece, they'll all be fulfilled from the buffer, so you'll only hit the FileReader once. – parsifal Mar 12 '13 at 18:56
  • parsifal: My one line is maximum 10 bytes, so it won't cause many disk reads. Thanks :) – high5 Mar 12 '13 at 18:59
  • parsifal: Could you please tell me the reason for using FileInputStream instead of FileReader? – high5 Mar 12 '13 at 19:09
  • @high5: FileReader doesn't allow you to specify the encoding, and encodings matter. – Michael Borgwardt Mar 12 '13 at 19:32
5

You are going through several layers of abstraction between the java code and the disk. There is the Java Virtual Machine and its specific implementation, and then there is the operating system that the JVM is running on, which is then communicating to the disk through some method (it may be a network disk, it may be a local raid, it may be a solid state drive, it may be a stream from a network).

The specifics of the disk IO are determined by the virtual machine and operating system and the underlying source of the data. It may be different for different vm's in how they ask for io requests - there is no way to determine this from within Java, nor is there a way to communicate at that level with the disk through Java.

  • Well, the actual problem is, I have to read some specified number of lines from a text file. So, I wondered if it is expensive in terms of disk I/Os to call readLine () that many times than calling some other function (if available) just once. – high5 Mar 12 '13 at 18:32
  • @high5 One can't say. You may get different performance with the HotSPot JVM compared to the OpenJDK JVM. You may get different performance on Windows compared to Linux. You may get different performance with a file on the network than one locally. Unless this performance is a real issue, don't worry about it. If it is, then use profiler tools to identify the location of the performance bottlenecks and address it then. – user40980 Mar 12 '13 at 18:36
  • +1 Also, the firmware on the drive's own internal controller board often does its own buffering. – Karl Bielefeldt Mar 12 '13 at 19:04
1

No. A BufferedReader stores data in its internal buffer, that's the entire point of the class. If there's enough data in there already, a call to readLine() will not issue another I/O request.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.