栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java 是否可以从InputStream读取超时?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 是否可以从InputStream读取超时?

使用

inputStream.available()

System.in.available()
返回0始终是可接受的。

我发现相反的情况-它总是返回可用字节数的最佳值。Javadoc适用于

InputStream.available()

Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream.

由于时间/陈旧性,估计是不可避免的。该数字可能是一次性的低估,因为不断有新数据到来。但是,它总是在下一个呼叫“赶上”-它应该考虑所有到达的数据,禁止在新呼叫时到达的数据。如果有数据,则永久返回0会导致上述情况失败。

首先警告

InputStream
的具体子类负责
available()

InputStream
是一个抽象类。它没有数据源。拥有可用数据毫无意义。因此,javadoc available()也指出:

The available method for class InputStream always returns 0.This method should be overridden by subclasses.

实际上,具体的输入流类确实会覆盖available(),提供有意义的值,而不是恒定的0。

第二个警告:确保在Windows中键入输入时使用回车符。

如果使用

System.in
,则程序仅在命令外壳程序移交时才接收输入。如果你使用文件重定向/管道(例如
somefile> java myJavaApp
somecommand | java myJavaApp
),则通常会立即移交输入数据。但是,如果你手动键入输入,则数据切换可能会延迟。例如,使用
Windows cmd.exe Shell
,数据将缓存在
cmd.exe Shell
中。数据仅在回车(控制-m或)后才传递到执行的Java程序。那是执行环境的限制。当然,只要Shell缓冲数据,
InputStream.available()
都将返回0-这是正确的行为。当时没有可用数据。一旦从外壳程序获得数据,该方法将返回一个值
>0
。注意:Cygwin使用cmd。

最简单的解决方案(无阻塞,因此无需超时)
只需使用此:

    byte[] inputData = new byte[1024];    int result = is.read(inputData, 0, is.available());      // result will indicate number of bytes read; -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);         // can alternatively use bufferedReader, guarded by isReady():         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 will indicate number of bytes read; -1 for EOF with no data read.


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/420226.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号