It is not uncommon to see a code snippet like this:
attached to a question wondering why the data is not being moved completely. The answer is that available() doesn't do what you think it does. If we look at the documentation for JavaDoc:java.io.InputStream :
It is clear that available() does not return the amount of data left to be read, but the amount of data that can be read without blocking (pausing to wait for more data from the file/socket/database/etc.). In some cases this may return zero while there are still bytes that should be read - the 0 means that there are 0 bytes available right now (with no blocking). This may happen for various reasons - a hard drive may be busy repositioning its magnetic reader, or a network connection may be busy, or perhaps you're waiting for a user somewhere to type something before their information may be sent. Or it may be because the file you're reading really has no additional bytes to read, because you've reached the end. Using available() you have no way of knowing whether or not you should try to read the bytes anyway.
A more correct way to use a stream to copy a file is to check the return value of read for the end-of-file value (-1):
When this code completes, you know that all the bytes really have been read and copied, because the while loop doesn't complete until read() returns -1, indicating the end of input.
Readers don't have an available() method, but they do have a ready() method, which is similar (and similarly useless in most cases). This method simply returns false if the reader has no chars available right now, just as available() would return 0. A return value of false does not (necessarily) mean that there are no more characters to read; it just means there will be some delay before you can read them.