从输入流中可能的定时读取
挑战在于设计一个名为 MaybeRead 的方法,它返回与 in.read() 相同的结果如果数据在指定的超时时间内可用。具体来说,如果在给定的超时时间内没有可用数据,maybeRead 将返回 -2。
最初,将 InputStream 包装在 Reader 或 InterruptibleChannel 中似乎可以提供解决方案,但两者都只能通过 InputStream 方法。此外,在此过程中避免任何线程生成至关重要。
尽管相信 in.available() 始终返回 0,但文档显示它提供了可用于读取而不会阻塞的字节的估计。虽然这个估计可能被低估,但它会赶上以下调用以考虑新到达的情况。
但是,InputStream 的子类处理它们自己的 available() 实现,并且具体实现会覆盖它以提供有意义的值。因此,仅仅使用 is.available() 是不够的。
对于非阻塞和无超时读取,请考虑以下解决方案:
byte[] inputData = new byte[1024]; int result = is.read(inputData, 0, is.available()); // -1 for EOF with no data read.
或
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); }
对于在超时内最大化缓冲区的更复杂的解决方案,请使用以下方法方法:
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; }
并按如下方式使用:
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.
以上是如何在不使用线程的情况下实现输入流的定时读取?的详细内容。更多信息请关注PHP中文网其他相关文章!