non-blocking read

Question:
How do I control blockingin Java.

For example, in telnet Iwould like to take an actionif the user presses a certainkey. This requiresnon-blocking read; I think?

Answer:
It is not currently possible in Java to set an arbitrary stream tobe non-blocking as you would with a call like fcntl(fd, F_SETFL, O_NONBLOCK)in Unix. However, there are a few ways of dealing with this, none ofwhich are entirely satisfactory.

If you are dealing with an InputStream, you can check its available()method before reading from it. The available() method will return thenumber of bytes that can be read from the stream without blocking.The problem with this is that you can’t count on every subclass ofInputStream to implement available() properly. For example, in JDK 1.1.3,the PushbackInputStream class has an incorrectly implemented available()method. This may have been fixed in the latest JDK by the time you readthis.

If you are dealing with a Reader subclass, you can check its ready() method.The ready() method will simply return true if you can read at least onecharacter from it without blocking. Since you don’t know how many charactersyou can read without blocking, you are forced to write rather inefficientcode that reads one character at a time, checking ready() before everyread. You also still have the problem of possibly unreliable implementationsof ready().

If you do not want to block indefinitely while reading from a socket’sinput stream, you can set a timeout on the socket using thejava.net.Socket setSoTimeout() method, which takes an integer representingthe maximum number of milliseconds to block on a read. A read from asocket is supposed to throw an InterruptedIOException, but from experienceI know that in practice it will also throw a SocketException. To detect thetimeout, you have to catch both of these exceptions.

However, you seem to be asking about how to deal with user input fromstandard input. There is no effective way of reading a character ata time from standard input without writing native code to disablecommand shell line buffering. In your telnet client example, you would want to create an AWT component from which you would interpret user inputby detecting a KeyEvent of type KeyEvent.KEY_PRESSED rather than readingfrom standard input.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: