如何从标准输入读取非阻塞?

pav*_*avi 14 java

    long end=System.currentTimeMillis()+60*10;
    InputStreamReader fileInputStream=new InputStreamReader(System.in);
    BufferedReader bufferedReader=new BufferedReader(fileInputStream);
    try
    {
        while((System.currentTimeMillis()<end) && (bufferedReader.readLine()!=null))
        {

        }
        bufferedReader.close();
    }
    catch(java.io.IOException e)
    {
        e.printStackTrace();
    }
Run Code Online (Sandbox Code Playgroud)

我实际上尝试在600毫秒的时间内完成上述操作,之后它不应该允许读取但缓冲读取器的读取线是阻塞的.请帮助

Mif*_*eet 11

使用BufferedReader.available()Sibbo建议不可靠.available()国家文件:

返回可以读取的字节数的估计值 ...使用此方法的返回值来分配缓冲区永远不正确.

换句话说,您不能依赖此值,例如,0即使某些字符实际可用,它也可以返回.

我做了一些研究,除非你能够从外部关闭进程输入流,否则你需要求助于来自不同线程的异步读取.您可以在此处找到如何在不逐行阻止的情况下阅读的示例.


更新:以下是上述链接的简化版代码:

public class NonblockingBufferedReader {
    private final BlockingQueue<String> lines = new LinkedBlockingQueue<String>();
    private volatile boolean closed = false;
    private Thread backgroundReaderThread = null;

    public NonblockingBufferedReader(final BufferedReader bufferedReader) {
        backgroundReaderThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (!Thread.interrupted()) {
                        String line = bufferedReader.readLine();
                        if (line == null) {
                            break;
                        }
                        lines.add(line);
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                } finally {
                    closed = true;
                }
            }
        });
        backgroundReaderThread.setDaemon(true);
        backgroundReaderThread.start();
    }

    public String readLine() throws IOException {
        try {
            return closed && lines.isEmpty() ? null : lines.poll(500L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            throw new IOException("The BackgroundReaderThread was interrupted!", e);
        }
    }

    public void close() {
        if (backgroundReaderThread != null) {
            backgroundReaderThread.interrupt();
            backgroundReaderThread = null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Sib*_*bbo 2

您可以使用 BufferedReader.available() > 0 检查是否有字符要读取。

String s;

while((System.currentTimeMillis()<end))
{
    if (bufferedReader.available() > 0)
        s += bufferedReader.readLine();
}

bufferedReader.close();
Run Code Online (Sandbox Code Playgroud)

  • read() 不保证线路已准备好,仅保证存在一些数据。readLine() 仍然可能阻塞。请参阅http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#ready%28%29 (10认同)
  • BufferedReader 中没有可用的方法,但我们已经准备好了,所以我尝试了一下并完成了。谢谢 sibbo。 (9认同)
  • 这还堵着!! (7认同)