从Java标准输入读取,无需轮询或不断阅读,也不浪费资源

时间:2014-01-24 00:51:51

标签: java

如果程序通过管道将数据发送到我的标准输入流,那么如何让我的Java程序自动检测新数据是否通过管道进入输入流,以便我可以读取它?

我知道我可以使用无限循环,不断读取和检查标准输入流。但这是无效的,需要大量资源。我的任务甚至不允许这样做。

它必须以某种方式同步。我可以在管道或标准输入上放置一个监听器:“嘿!现在读取标准输入!新数据即将到来!”或者我可以让管道发送中断或我该怎么做?

3 个答案:

答案 0 :(得分:2)

正如其他人所说,没有办法检查输入是否可以从InputStream(或Reader)获得,该输入既不会阻止当前线程......也可能涉及昂贵轮询。

简单的解决方案就是尝试读取,并阻止数据到达。此解决方案可以,除非 ...

  • 您希望在等待数据到达时执行其他操作,或
  • 数据可能会到达许多输入流之一。

在这种情况下,您需要使用NIO选择器(允许您等待数据到达一组流中的一个,或者使用不同的线程从每个流中读取数据,以及其他线程来处理它) (或做其他事情)。在后一种情况下,您可能需要某种排队机制来将“消息”从阅读器线程/线程传递到处理线程/线程。

然而,最重要的是,如果没有更多应用程序的详细信息,我们无法提供一个好的具体解决方案。


一条建议:不要尝试使用InputStream.available()Reader.ready()。这些涉及轮询......并且它们指定的语义无法明确告诉您read 是否阻止。它们基本没用......

答案 1 :(得分:1)

执行此操作的标准方法是在输入流上使用read方法? 如果数据是文本,那么您可以使用readLine方法。

请参阅此信息link

当然,调用此代码的步骤将会阻塞,因此理想情况下,此代码将位于不同的线程中。

答案 2 :(得分:0)

简单地说,没有免费午餐这样的东西:D

如果您要求同步消息,如果不是您,其他人则必须进行轮询。所以基本上,如果存在这样的同步(或事件驱动)系统,应该对性能没有影响。 (除非操作系统本身具有一些性能优势)。

尽管如此,当我们讨论java标准输入流时,程序,jvm和os之间的契约已经确定。所以只是回答你的问题,你必须轮询(如果你愿意,可以在一个新的主题中)。

希望这有帮助。