这个问题可以更好地改写为:How do you detect EOF in InputStream without blocking我有一个能够直接从 System.in 获取输入的 java 程序(不使用扫描器),我也可以像任何程序一样直接将输入输入到 java 程序中。但是,当我将输入输入到程序中时,程序会继续运行。这个想法是如果输入被输入到程序中,则停止程序,但如果我们正在等待用户输入,则保持程序运行。我的问题是如何使用 InputStream 来检测管道何时结束(并结束程序)?如果我使用的是 Scanner,我知道我可以使用Scanner#hasNext()来检测我是否可以阅读更多内容,但是如果可能的话,我想只使用 InputStream 来做到这一点。我的代码目前看起来与此类似:final InputStream in = System.in; // sometimes in won't be System.infinal byte[] buffer = new byte[1024];while(true){ int len; // the reason I use in.available() is so I only read if in.read() won't block while(in.available() > 0 && (len = in.read(buffer)) > -1){ String s = new String(buffer, 0, len); // do something with string } // sometimes do other stuff not relevant to this question}我愿意接受更简单的解决方案。我不使用 Scanner 对象的原因是因为我需要一次读取单个字符,而不仅仅是一次读取行。这个程序的目的不仅仅是来自用户的输入,大多数时候输入甚至不是来自 System.in,我只是在上面的例子中包含了 System.in,因为它有时是 System.in编辑:无论出于何种原因,我花了大约 2 个小时的时间在互联网上搜索一个简单的解决方案。我试过只使用 InputStream,甚至将我的代码转换为使用 ReadableByteChannel(使用 Channels.newChannel() 创建)来查看是否可行。我能找到的每个包装 InputStream 的实现都是阻塞的。我想解决这个问题的唯一方法是使用另一个线程。祝未来的观众好运。
3 回答
哔哔one
TA贡献1854条经验 获得超8个赞
你真的不需要in.available()
。当管道耗尽时,您的变量len
将是-1
并且内部 while 循环将结束。您可以break
根据需要只使用外部 while 循环。
慕无忌1623718
TA贡献1744条经验 获得超4个赞
坐在 while 循环中并调用 in.available 效率不高。它将使用大量的 CPU。
如果你调用 in.read() 并且它返回 -1 则意味着没有更多的输入可以读取。所以你应该这样做,但当然它会阻塞。
如果您需要在此过程中执行其他操作,请为其他代码使用不同的线程。确保将其他线程设置为守护线程,这样当主线程的方法完成时,它就不会让程序继续运行。
慕仙森
TA贡献1827条经验 获得超7个赞
只需记住是否read()返回-1,即增加范围len。
final InputStream in = System.in;
final byte[] buffer = new byte[1024];
for (int len = 0; len != -1; ) {
while (in.available() > 0 && (len = in.read(buffer)) != -1) {
String s = new String(buffer, 0, len);
// do something with string
}
// do other stuff
}
添加回答
举报
0/150
提交
取消