0

InputStream.available() javadoc:

Returns the number of bytes that can be read (or skipped over) from this input stream without blocking

  1. I think that blocking means that thread from which I called read() is blocked (control flow doesn't go further) until that read() returns. In this sense I cannot see any scenario in which read() can be called without blocking.

  2. Another meaning of blocking may be that if I want to read 3 bytes and have none or just 1 byte available, read() would block and wait for more bytes to appear - but I cant't understand it that way b/c then calling read() and trying to read more than available may cause eternal blocking (just imaging reading 100 bytes from a file of 10 bytes).

In which sense java.io is blocking (1) or (2)?

I cannot simulate a situation when read methods of IO block (in sense (2)) with FileInputStream or ByteArrayInputStream:

        // file content is: 1 2 3       
        FileInputStream myStream = new FileInputStream("d:\\file.txt");
        byte[] b = new byte[100];
        myStream.read(b);
        System.out.println("control reached here?");
        System.out.println(Arrays.toString(b));

Output:

reached here?
[122, 100, 122, 120, 118, 122, 120, 32, 118, 122, 120, 118, 32, 122, 120, 118, 32, 122, 118, 99, 122, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Second call myStream.read(b) would just return -1 also without blocking.

In which scenario does blocking occur?

I thought it occurs if I try to read 5 bytes and there is three. If there is none it means EOF / end-of-stream and -1 is returned (no blocking either).

P.S. I tend to think that java.io is both (1) and (2): it is synchronous (1) and blocking (2), but that blocking is really observed only working with sockets (Socket.getInputStream() / Socket.getOutputStream()).

user10777718
  • 723
  • 4
  • 16

2 Answers2

1

More or less option 2, but you don't have to worry about read blocking even if there's some data to process already.

Here's a tip: Don't use available(). It's effectively useless, the information it grants does not really let you do things that you otherwise couldn't do.

Let's say you have a TCP network connection. Until you or the opposite side hangs up the connection, there is no limit to how many bytes can be sent across the line, but on the flipside, it's possible that there are, say, 10 bytes left to read and no more will be forthcoming for a while because the sender is, for now, silent.

Let's say you then do this:

byte[] b = new byte[100];
int r = in.read(b);

What's going to happen here, is that r will be 10, the first 10 slots in your b will be filled, and that's that. read 'smartly' returns: It does NOT return if there are 0 bytes (read guarantees that it'll block until it either reads at least 1 byte, or the stream is closed, in which case it returns -1)... and if there are bytes to read, it reads an efficient chunk of it.

blocking, specifically, means that the thread will be paused and won't resume until something changes. (bytes come in, or the stream is closed).

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
0

Scenario 2 is the meaning.

(Updated after some experimentation)

It seems that local disk file I/O is not considered blocking. For a FileInputStream, the available() method returns the remaining length of the file. That is, if the file is 91764 bytes long, and you read 4 bytes, after that available() will return 91760.

I find that result surprising; your thread will surely block for disk I/O if you try to read those 91760 bytes.

The result is more understandable for network socket connections. The amount of data that may arrive from the remote system in future is of course unknown; available() will tell you how much has already arrived and can be read now. In this case, 'blocking' would be of indefinite duration - waiting until the remote host may send, which is outside the knowledge of the I/O system. at leaves 20 bytes available for a further read without blocking.

  • *Asynchronous* allows you to do other work in the meantime. Non-blocking, if it existed for files, which it doesn't, would either succeed or fail instantaneously. – user207421 Apr 13 '19 at 21:17
  • You're of course right. Thanks. Anyway, FWiW, I rewrote my answer. –  Apr 13 '19 at 22:08
  • You shouldn't state what `availagle()` returns for a `FileInoutStreM`. That's just what FIONREAD happens to do in a number of systems.it is t specified anywhere, neither in Java Nor AFAIK for `ioctl()` either. Possibly the OP is reading a networked file. – user207421 Apr 14 '19 at 01:17