当前位置: 首页 > 面试题库 >

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

江渊
2023-03-14
问题内容

具体来说,问题是编写这样的方法:

int maybeRead(InputStream in, long timeout)

如果数据在“超时”毫秒内可用,则返回值与in.read()相同,否则为-2。在方法返回之前,所有产生的线程必须退出。

为避免自变量,此处的主题为java.io.InputStream,如Sun(任何Java版本)所记录。请注意,这并不像看起来那么简单。以下是Sun的文档直接支持的一些事实。

  1. in.read()方法可能是不可中断的。
  2. 将InputStream包装在Reader或InterruptibleChannel中没有帮助,因为所有这些类都可以做的是InputStream的调用方法。如果可以使用这些类,则可以编写一个直接在InputStream上执行相同逻辑的解决方案。

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

  4. in.close()方法可能会阻止或不执行任何操作。
  5. 没有杀死另一线程的一般方法

问题答案:

使用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 myJavaAppsomecommand | 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.


 类似资料:
  • 问题内容: 有什么方法可以从中创建对象吗? 我的要求是从RAR读取文件。我不是要写一个临时文件,而是要在RAR存档中找到一个文件。 问题答案: 您需要创建新文件并将内容复制到该文件: 我使用方便来避免手动复制流。它还具有内置缓冲。

  • 问题内容: 我已经创建了可执行的jar文件(使用Eclipse),在jar中包含一组图像(.png)文件。所以我添加了一个源文件夹,其中所有图像都位于项目的文件夹中。代码必须访问这些文件才能使用创建BufferedImage 较早前,为了获得我使用的路径 在执行jar时,它抛出错误 URI不是分层的 所以现在我正在使用 但是如何使ImageIO从Inputstream读取?我试过如下 抛出错误 I

  • 问题内容: 在一个项目上,我通过一个类似于控制台的小窗口运行Java应用程序。由于这里有一个很棒的社区,我设法通过从流程输出数据来解决问题,但是由于没有输入流,我运行的命令行应用程序将不断出错。 基于该线程中最后一个有用的答复,我想我将以类似的方式实现该实现,但是在javadocs中以及整个google和互联网中寻找某个类,该类确实没有发现任何解释方法。 因此,我需要一些链接,示例,教程,示例代码

  • 问题内容: 在 Android平台上从InputStream读取时,我遇到一个奇怪的问题。我不确定这是否是Android特有的问题,或者 总体上我做错了什么。 唯一特定于Android的是此调用: 这会从Android资产返回文件的InputStream。无论如何, 这是我遇到的问题: 当read()执行时,它抛出IOException。奇怪的是, 如果我进行了两个连续的单字节读取(或任意数量的单

  • 我试图分块读取输入流并写入文件以避免内存问题,我接收json格式的数据,并使用以下代码写入文件。 我的问题是,大多数json都写得很好,虽然其中一些包含损坏的数据,但我不确定我是否正确地将CharBuffer与BufferedReader一起使用,我观察到的另一件事是,对于少量数据,它正确地将CharBuffer写入文件,当我从服务器接收到更大的数据(大约2MB的输入流-不是很大)时,我通常会遇到

  • 是否可以同时从套接字读取和写入?我有一个连续读取套接字的线程。由于只有一个线程从套接字读取,因此读取操作是线程安全的。现在我有很多线程(比如 100 个)写入套接字。因此,很明显,我必须通过做这样的事情来使写入操作线程安全, 现在我有一个线程不断调用readMessage()函数(在while循环中)。据我所知,如果套接字上没有要读取的消息,语句< code > inputstream . rea