首页 >Java >java教程 >如何在不使用线程的情况下实现输入流的定时读取?

如何在不使用线程的情况下实现输入流的定时读取?

Susan Sarandon
Susan Sarandon原创
2024-12-26 15:54:11854浏览

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

从输入流中可能的定时读取

挑战在于设计一个名为 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 &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;
 }

并按如下方式使用:

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn