How do i check if inputstream contains no data? - java

I am using the javax.comm package to perform read and write operations on the SerialPort.
I have created an object of type InputStream as InputStream in;
My question is ....
Irrespective of data availibility on the SerialPort, in.available() always returns a zero due to which I am not able to decide whether bytes are available or not.
If i use the in.read() directly, it seems to block the execution forever..
Please help...
Awaiting your reply..
You can also mail me on my email address..
In anticipation of your reply....
Utsav

This is typical behavior of block I/O. The read() is going to block till some bytes are available, EOF or error. You should create a new thread and just wait for more data.
Don't use available() call because it may create a fast loop and drive up your CPU usage. If you really want do this in a single thread, looking into NIO.

Related

How to set a timeout when reading from a Java RandomAccessFile

I am writing to and reading from a Linux file in java, which in reality is a communication port to a hardware device. To do this I use RandomAccessFile (I'll explain why later) and it works well in most cases. But sometimes a byte is lost and then my routine blocks indefinitely since there is no timeout on the read method.
To give some more details on the file: it is a USB receipt printer that creates a file called /dev/usb/lp0 and though I can use a cups driver to print, I still need the low level communication through this file to query the status of the printer.
The reason I use RandomAccessFile is that I can have the same object for both reading and writing.
I tried to make a version with InputStream and OutputStream instead (since that would allow me to use the available() method to implement my timeout). But when I first open the InputStream and then the OutputStream I get an exception when opening the OutputStream since the file is occupied.
I tried writing with the OutputStream and then closing it before opening the InputStream to read, but then I lose some or all of the reply before it has opened the InputStream.
I tried switching to channels instead (Files.newByteChannel()). This also allows me to have just one object, and the documentation says it only reads the bytes available and returns the count (which also allows me to implement a timeout). But it blocks in the read method anyway when there is nothing to read, despite what the documentation says.
I also tried a number of ways to implement timeouts on the RandomAccessFile using threads.
The first approach was to start a separate thread at the same time as starting to read, and if the timeout elapsed in the thread I closed the file from the thread, hoping that this would unlock the read() operation with an exception, but it didn't (it stayed blocked).
I also tried to do the read in a separate thread and brutally kill it with the deprecated Thread.stop() once the time had elapsed. This worked one time, but it was not possible to reopen the file again after that.
The only solution I have made work is to have a separate thread that continuously calls read, and whenever it gets a byte it puts it in a LinkedBlockingQueue, which I can read from with a timeout. This approach works, but the drawback is that I can never close the file (again for the same reasons explained above, I can't unblock a blocked read). And my application requires that I sometimes close this connection to the hardware.
Anyone who can think of a way to read from a file with timeout that would work in my case (that allows me to have both a read and a write access open to the file at the same time)?
I am using Java8 by the way.

when does FileInputStream.read() block?

The question is similar to the following two questions.
Java InputStream blocking read
Why is the FileInputStream read() not blocking?
But I still cannot fully understand it.
So far I think the read() method in following code will block due to the empty file 'test.txt'.
FileInputStream fis = new FileInputStream("c:/test.txt");
System.out.println(fis.read());
System.out.println("to the end");
Actually it will print -1, I want to know why.
The javadoc says This method blocks if no input is yet available.
What does 'no input is available' mean?
thanks.
The answer to your question can be found in the JavaDoc for .read():
This method blocks if no input is yet available.
and
Returns: the next byte of data, or -1 if the end of the file is reached.
So, an empty file will get you an immediate -1 (instead of read() blocking) as
there is input available, since the file exists
...but it is empty, so immediate EOF.
The ...No input is yet available... situation could occur eg. when one was to read from a named pipe instead of a plain file, and the other side of the pipe hasn't written anything yet.
Cheers,
FileInputStream can be used to read from things other than ordinary files. One obvious example is a named pipe: if you try to read from a pipe before the other side has written to it, the read operation will block.
This maybe interperted as follows: FileInputStream.read invokes a native method, the native method makes the read system call and blocks waiting for OS to read the bytes from file into a buffer and returns when ready. That is, FileInputStream.read uses synchronous I/O to reads data from a file as opposed to non-blocking, asynchronous I/O.
You can't interpret 'no input is available' as 'you are positioned at EOF and no more input will ever be available'. They are different conditions. The latter returns -1.
In general, all reads from files block until the data is available. The disk has to come around to the right point and the head has to seek to the right track. You also need to consider files that are on shared drives, or files that are named pipes, both of which involve network operations, which can also block.

Write contents of an InputStream (blocking) to a non-blocking socket

I'm programming a simple Java NIO server and have a little headache: I get normal InputStreams i need to pipe to my clients. I have a single thread performing all writes, so this creates a problem: if the InputStream blocks, all other connection writing will be paused.
I can use InputStream.available() to check if there are any incoming data I can read without blocking, but if I've reached end-of-stream it seems I must call read() to know.
This creates a major headache for me, but I can't possibly believe I'm the first to have this problem.
The only options I've come up with so far:
Have a separate thread for each InputStream, however that's just silly since I'm using non-blocking I/O in the first place. I could also have a thread pool doing this but then again that limits the amount of simultaneous clients I can pipe the InputStream to.
Have a separate thread reading these streams with a timeout (using another thread to interrupt if reading has lasted longer than a certain amount of time), but that'll most certainly choke the data flow should I have many open InputStreams not delivering data.
Of course, if there was a magic InputStream.isEof() or isClosed() then this wouldn't be any problem at all :'(
".....Have a separate thread for each InputStream, however that's just silly since I'm using non-blocking I/O in the first place...."
It's not silly at all. First you need to check whether you can retrieve a SelectableChannel from your InputStream implementation. If it does you are lucky and you can just register it with a selector and do as usual. But chances are that your InputStream may have a channel that's not a SelectableChannel, in which case "Have a separate thread for each InputStream" is the obvious thing to do and probably the right thing to do.
Note that there is a similar problem discussed in SO about not able to get a SelectableChannel from an inputstream. Unfortunately you are stuck.
I have a single thread performing all
writes
Have you stopped to consider whether that is part of the problem rather than part of the solution?

What does InputStream.available() do in Java?

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?
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.
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

Java: ignoring an input stream - will buffers overflow and bad things happen?

I have a client connecting to my server. The client sends some messages to the server which I do not care about and do not want to waste time parsing its messages if I'm not going to be using them. All the i/o I'm using is simple java i/o, not nio.
If I create the input stream and just never read from it, can that buffer fill up and cause problems? If so, is there something I can do or a property I can set to have it just throw away data that it sees?
Now what if the server doesn't create the input stream at all? Will that cause any problems on the client/sending side?
Please let me know.
Thanks,
jbu
When you accept a connection from a client, you get an InputStream. If you don't read from that stream, the client's data will buffer up. Eventually, the buffer will fill up and the client will block when it tries to write more data. If the client writes all of its data before reading a response from the server, you will end up with a pretty classic deadlock situation. If you really don't care about the data from the client, just read (or call skip) until EOF and drop the data. Alternatively, if it's not a standard request/response (like HTTP) protocol, fire up a new thread that continually reads the stream to keep it from getting backed up.
If you get no useful data from the client, what's the point of allowing it to connect?
I'm not sure of the implications of never reading from a buffer in Java -- I'd guess that eventually the OS would stop accepting data on that socket, but I'm not sure there.
Why don't you just call the skip method of your InputStream occasionally with a large number, to ensure that you discard the data?
InputStream in = ....
byte[] buffer = new byte[4096] // or whatever
while(true)
in.read(buffer);
if you accept the connection, you should read the data. to tell you the truth i have never seen (or could forsee) a situation where this (a server that ignores all data) could be useful.
I think you get the InputStream once you accept the request, so if you don't acknowledge that request the underlying framework (i.e. tomcat) will drop that request (after some lapsed time).
Regards.

Categories

Resources