Home > OS >  InputStream.ready() [method]
InputStream.ready() [method]

Time:07-01

Can someone say that code below is good way to read all file? Maybe the first code block is using the ready method in a wrong way.

try (var br = new BufferedReader(new FileReader("/some-file.txt"))) {
 while (br.ready()) {
   System.out.println(br.readLine());
 }
}

Or maybe is better approach to read file without method ready?

try (var br = new BufferedReader(new FileReader("/some-file.txt"))) {
  while (true) {
     var line = br.readLine();
     if (line == null) break;
     System.out.println(line);
 }
}

I tested that two blocks and all blocks print all file content, but I've never saw the first way over internet.

CodePudding user response:

Here's the documentation of BufferedReader#ready():

Tells whether this stream is ready to be read. A buffered character stream is ready if the buffer is not empty, or if the underlying character stream is ready.

[...]

Returns:

True if the next read() is guaranteed not to block for input, false otherwise. Note that returning false does not guarantee that the next read will block.

So, this method is about whether or not the next read will block. You're trying to read the whole file in one go, which means you don't really care if the next read will block. Worse, what if the reader is not ready? Your loop will break, you'll close the file, and the code will continue on without having read the whole source.

A typical way to code what you're doing is:

try (var reader = new BufferedReader(new FileReader("/some-file.txt"))) {
  String line;
  while ((line = reader.readLine()) != null) {
     System.out.println(line);
  }
}

Since readLine() is contracted to return null only when the end of the stream is reached.

Note of caution though. The above did not specify a charset, which means the default charset is used (see documentation for Java 17 and before and Java 18 ). You can use FileReader(String,Charset) to specify a charset.


There's also the java.nio.file.* API that you can use to do the same thing. For example:

try (var stream = Files.lines(Path.of("/some-file.txt"))) {
  stream.forEachOrdered(System.out::println);
}

The above uses the UTF-8 charset. You can use Files#lines(Path,Charset) to use a specific charset.

CodePudding user response:

I think everyone does it in a different way (you could also read each byte using loops) but there is a way to read the whole file at once without loops

String file = new String(Files.readAllBytes(Paths.get("file")));

You can also use Files.readAllLines depending on what you want to do with data in file.

edit. First comment under your question also shows a better way

  • Related