Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何读取标准输入的非阻塞数据? long end=System.currentTimeMillis()+60*10; InputStreamReader文件InputStream=新的InputStreamReader(System.in); BufferedReader BufferedReader=新的BufferedReader(fileInputStream); 尝试 { while((System.currentTimeMillis()_Java - Fatal编程技术网

Java 如何读取标准输入的非阻塞数据? long end=System.currentTimeMillis()+60*10; InputStreamReader文件InputStream=新的InputStreamReader(System.in); BufferedReader BufferedReader=新的BufferedReader(fileInputStream); 尝试 { while((System.currentTimeMillis()

Java 如何读取标准输入的非阻塞数据? long end=System.currentTimeMillis()+60*10; InputStreamReader文件InputStream=新的InputStreamReader(System.in); BufferedReader BufferedReader=新的BufferedReader(fileInputStream); 尝试 { while((System.currentTimeMillis(),java,Java,如果有字符要读取,可以使用BufferedReader.available()>0进行检查 long end=System.currentTimeMillis()+60*10; InputStreamReader fileInputStream=new InputStreamReader(System.in); BufferedReader bufferedReader=new BufferedReader(fileInputStream); try {

如果有字符要读取,可以使用BufferedReader.available()>0进行检查

    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();
    }
字符串s;
while((System.currentTimeMillis()0)
s+=bufferedReader.readLine();
}
bufferedReader.close();
BufferReader.readLine()如果一行非常长,如1M字符,则会阻塞很长时间

你的文件包含这么长的行吗

如果是,您可能必须将行分开,或者使用每字符读取方法,如BufferReader.read()。

long-end=System.currentTimeMillis()+60*10;
InputStreamReader文件InputStream=新的InputStreamReader(System.in);
BufferedReader BufferedReader=新的BufferedReader(fileInputStream);
试一试{
while((System.currentTimeMillis()
使用Sibbo建议的
BufferedReader.available()
是不可靠的。
available()
的文档说明:

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

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

我做了一些研究,除非您能够从外部关闭进程输入流,否则您需要从不同的线程进行异步读取。您可以找到一个示例,说明如何在不逐行阻塞的情况下进行读取


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

long end=System.currentTimeMillis()+60*10;
InputStreamReader fileInputStream = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(fileInputStream);
try {
    while ((System.currentTimeMillis() < end)) {
        if (bufferedReader.ready()) {
            System.out.println(bufferedReader.readLine());
        }
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (bufferedReader != null) {
            bufferedReader.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
公共类非阻塞BufferedReader{
private final BlockingQueue lines=新建LinkedBlockingQueue();
私有易失性布尔闭合=假;
私有线程backgroundReaderThread=null;
公共非阻塞BufferedReader(最终BufferedReader BufferedReader){
backgroundReaderThread=新线程(new Runnable(){
@凌驾
公开募捐{
试一试{
而(!Thread.interrupted()){
String line=bufferedReader.readLine();
如果(行==null){
打破
}
行。添加(行);
}
}捕获(IOE异常){
抛出新的运行时异常(e);
}最后{
关闭=真;
}
}
});
backgroundReaderThread.setDaemon(true);
backgroundReaderThread.start();
}
公共字符串readLine()引发IOException{
试一试{
返回closed&&lines.isEmpty()?null:lines.poll(500L,TimeUnit.ms);
}捕捉(中断异常e){
抛出新IOException(“BackgroundReaderThread被中断!”,e);
}
}
公众假期结束(){
if(backgroundReaderThread!=null){
backgroundReaderThread.interrupt();
backgroundReaderThread=null;
}
}
}

唯一可靠的方法是启动工作线程并在其中执行实际读取,而调用线程将监视延迟


如果工作线程等待的时间超过允许的时间,主线程将终止它并引发异常。

我假设您会给用户很长的时间来实际编写内容。System.in.available()?注意:这也是一个估计值,正如@Mifeet在下面指出的,BufferedReader中没有调用可用的方法,但我们已经准备好了,所以我尝试了它并完成了。谢谢sibbo。好的,我忘记了,可用()方法是由InputStream实现的;)ready()不保证行准备好的,只有在存在一些数据的情况下。readLine()仍然可以阻止。看,这仍然是阻止!!不,实际上我只是在特定的时间间隔内读取少量数据。我是通过ready方法完成的。谢谢你的建议。bufferedReader.readLine仍然可以阻止你的线程。如果你的线程池中的所有线程都在bufferedReader.readLine()上被阻止然后线程池的调用者/使用者最终将被阻塞,因此阻塞系统为什么要使用带有超时的
poll
?因为
lines.isEmpty()
失败,这意味着行至少包含一个元素。这里真的需要基于时间的轮询吗?@insumity是的,你可能就在那里。除非有人从多个线程读取行,否则可能不需要轮询。@Mifeet非常感谢你的回答。是否有完整代码的链接镜像,因为链接死了?
long end=System.currentTimeMillis()+60*10;
InputStreamReader fileInputStream = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(fileInputStream);
try {
    while ((System.currentTimeMillis() < end)) {
        if (bufferedReader.ready()) {
            System.out.println(bufferedReader.readLine());
        }
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (bufferedReader != null) {
            bufferedReader.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
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;
        }
    }
}