What does InputStream.available() do in Java?

2019-01-08 10:10发布

What does InputStream.available() do in Java? I read the documentation, but I still cannot make it out.

The doc says:

Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream. The next caller might be the same thread or or another thread.

The available method for class InputStream always returns 0.

What do they mean by blocking? Does it just mean a synchronized call?

And most of all, what is the purpose of the available() method?

4条回答
祖国的老花朵
2楼-- · 2019-01-08 10:16

In InputStreams, read() calls are said to be "blocking" method calls. That means that if no data is available at the time of the method call, the method will wait for data to be made available.

The available() method tells you how many bytes can be read until the read() call will block the execution flow of your program. On most of the input streams, all call to read() are blocking, that's why available returns 0 by default.

However, on some streams (such as BufferedInputStream, that have an internal buffer), some bytes are read and kept in memory, so you can read them without blocking the program flow. In this case, the available() method tells you how many bytes are kept in the buffer.

查看更多
萌系小妹纸
3楼-- · 2019-01-08 10:24

Consider if you write software VERY BADLY.. and you write an operating system.

This operating system takes keyboard input amongst other things.

So you ask your OS to go and get some keyboard input, but there are no keys pressed and none in the buffer. your Whole OS will then HANG DEAD until it gets a keyboard input.

Contrast this with 'look ahead', you ask if the KB has any characters BEFORE making the call. You get the answer NO, so your OS then goes and does something else.

That is WHY you should care, now if you then multiply that by every other potentially blocking task, you can see why 'look ahead' is critical.

Because It also applies to OUTPUT: A memory to a disk-drive interface can also flood data to the disk-drive faster than it can process it. if you do not know the drive buffer is flooded with data, then the task will block until the buffer can accept more data.

This also highlights the nonsense of 'there are very few useful uses.'

查看更多
【Aperson】
4楼-- · 2019-01-08 10:28

One of possibly-practical usages of available() is using it for choosing a reasonable buffer length.

static final int LEN = 4096;

long copy(InputStream in, OutputStream out) throws IOException {
    int count = 0L;
    int avl = in.available();
    if (avl == 0) {
        // 0 returned without IOException? possibly mean eof?
        return 0L;
    }
    //byte[] buf = new byte[avl == 0 ? LEN : Math.min(avl, LEN)];
    byte[] buf = new byte[Math.min(avl, LEN)];
    for (int len; (len = in.read(buf)) != -1; count+= len) {
        out.write(buf, 0, len);
    }
    return count;
}

The document says,

Returns: an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking or 0 when it reaches the end of the input stream.

And

A subclass' implementation of this method may choose to throw an IOException if this input stream has been closed by invoking the close() method.

UPDATE

I already know the idea is not recommended. I've known that risk even before the JDK doc warned. (I once tried to allocated a buffer from the available of few GB sized FileInputStream.)

JDK8/InputStream#available

It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.

JDK5/InputStream#availabe

But, in programming, there should no never or always wrong code. That's what I'm believing.

查看更多
混吃等死
5楼-- · 2019-01-08 10:39

Blocking doesn't relate to threading or synchronisation here. Instead it relates to blocking IO (see this for more info). If you issue a request to read, and the channel has none available, a blocking call will wait (or block) until data is available (or the channel is closed, throws an exception etc.)

So why use available() ? So you can determine how many bytes to read, or determine whether you're going to block.

Note that Java has non-blocking IO capabilities as well. See here for more details

查看更多
登录 后发表回答