Home > Java > javaTutorial > How to Implement a Timed Read from an InputStream Without Threading?

How to Implement a Timed Read from an InputStream Without Threading?

Susan Sarandon
Release: 2024-12-26 15:54:11
Original
853 people have browsed it

How to Implement a Timed Read from an InputStream Without Threading?

Possible Timed Reads from an InputStream

The challenge lies in designing a method called maybeRead that returns the same result as in.read() if data is available within a specified timeout. Specifically, maybeRead returns -2 if no data is available within the given timeout.

Initially, it seems wrapping InputStream in a Reader or InterruptibleChannel could offer a solution, but both only pass through InputStream methods. Additionally, it is critical to avoid any thread spawn during this process.

Despite beliefs that in.available() always returns 0, documentation reveals it provides an estimate of the bytes available for reading without blocking. While this estimate may be underestimated, it catches up on the following call to account for new arrivals.

However, subclasses of InputStream handle their own implementation of available(), and concrete implementations override it to give meaningful values. Hence, simply using is.available() isn't sufficient.

For non-blocking and timeout-less reads, consider the following solutions:

byte[] inputData = new byte[1024];
int result = is.read(inputData, 0, is.available());  // -1 for EOF with no data read.
Copy after login

Or

BufferedReader br = new BufferedReader(new InputStreamReader(System.in, Charset.forName("ISO-8859-1")),1024);
// ...
         // inside some iteration / processing logic:
         if (br.ready()) {
             int readCount = br.read(inputData, bufferOffset, inputData.length-bufferOffset);
         }
Copy after login

For a more intricate solution that maximizes the buffer within a timeout, utilize the below method:

public static int readInputStreamWithTimeout(InputStream is, byte[] b, int timeoutMillis)
     throws IOException  {
     int bufferOffset = 0;
     long maxTimeMillis = System.currentTimeMillis() + timeoutMillis;
     while (System.currentTimeMillis() < maxTimeMillis &amp;&amp; bufferOffset < b.length) {
         int readLength = java.lang.Math.min(is.available(),b.length-bufferOffset);
         int readResult = is.read(b, bufferOffset, readLength);
         if (readResult == -1) break;
         bufferOffset += readResult;
     }
     return bufferOffset;
 }
Copy after login

And use it as follows:

byte[] inputData = new byte[1024];
int readCount = readInputStreamWithTimeout(System.in, inputData, 6000);  // 6 second timeout
// readCount indicates bytes read; -1 for EOF with no data read.
Copy after login

The above is the detailed content of How to Implement a Timed Read from an InputStream Without Threading?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template