Home >Java >javaTutorial >Can Java's InputStream be Read with a Timeout, and How?

Can Java's InputStream be Read with a Timeout, and How?

DDD
DDDOriginal
2024-12-25 18:21:15319browse

Can Java's InputStream be Read with a Timeout, and How?

Can Data Be Read from an InputStream with a Timeout?

The question centers around developing a method that can read from an InputStream within a specified timeout period. Such a method, maybeRead, aims to return the same result as the read() method in InputStream when data is available within the allotted time, or -2 if no data is available. The challenge lies in ensuring that any spawned threads are terminated during execution.

Java InputStream Limitations

Before exploring potential solutions, it's essential to acknowledge specific limitations of Java InputStream:

  1. read() may be non-interruptible, preventing interruptions during data retrieval.
  2. Wrapping InputStream in Reader or InterruptibleChannel offers no solution since they rely solely on InputStream methods.
  3. available() can legally return 0, even when data is present.
  4. close() may block or have no effect.
  5. No inherent mechanism exists to terminate other threads.

Combatting the Limitations

Utilizing InputStream.available()

Despite the documentation stating that available() can return 0, evidence suggests it provides accurate estimates of available data. Concrete InputStream subclasses strategically override available() to provide meaningful information.

Platform-Specific Caveats

Windows/Cygwin: Input is only provided upon pressing "Return." Otherwise, InputStream.available() returns 0 as expected.

Simple Solution (No Blocking)

byte[] inputData = new byte[1024];
int result = is.read(inputData, 0, is.available());  // Reads as much data as immediately available

Comprehensive Solution (Maximal Data Acquisition)

public static int readInputStreamWithTimeout(InputStream is, byte[] b, int timeoutMillis)
     throws IOException  {
     int bufferOffset = 0;
     long maxTimeMillis = System.currentTimeMillis() + timeoutMillis;
     while (System.currentTimeMillis() < maxTimeMillis && 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;
 }

Usage:

byte[] inputData = new byte[1024];
int readCount = readInputStreamWithTimeout(System.in, inputData, 6000);  // 6 second timeout

The above is the detailed content of Can Java's InputStream be Read with a Timeout, and How?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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