0

这是一个模拟InputStream慢流的模拟:

class SlowInputStream extends InputStream{
    private String internal = "5 6\nNext Line\n";
    private int position = 0;

    @Override
    public int available(){
        if(position==internal.length()) return 0;
        else return 1;
    }

    @Override
    public int read() throws IOException {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new IOException("Sleep Interrupted");
        }
        if(position==internal.length()) return -1;
        return internal.charAt(position++);

    }

}

这是测试代码:

    Scanner s = new Scanner(new SlowInputStream());

    int i=s.nextInt();
    System.out.println("i="+i);
    int j=s.nextInt();
    System.out.println("j="+j);
    s.nextLine();
    String line = s.nextLine();
    System.out.println("line="+line);

    s.close();

上述代码的行为是它会停止一段时间并打印三行。什么代码可以输出相同的东西,但在两行之间分割等待时间?

4

2 回答 2

0

您还需要覆盖 read(byte[], int, int) 。你最好扩展FilterInoutStream:这就是它的用途。

于 2013-01-08T08:46:18.300 回答
-1

如果 aScanner是从 中创建的InputStream,它将尝试每次读取特定数量的数据,以提高性能。在我的机器中,数量是 4096 字节。这就是为什么在这个例子中它总是一直等到同时打印所有结果。

要绕过此缓存机制Readable,应使用接口而不是原始流。因为没有已知的实现可以这样做,所以必须实现自己的。(如果有人知道这样的事情,请告诉我)所以下面的代码可以完成这项工作:

Scanner s = new Scanner(new Readable(){

    private InputStream is = new SlowInputStream();

    public int read(CharBuffer arg0) throws IOException {
        int i = is.read();
        if(i>=0){
            arg0.append((char)i);
            return 1;
        } else return -1;
    }

});

int i=s.nextInt();
System.out.println("i="+i);
int j=s.nextInt();
System.out.println("j="+j);
s.nextLine();
String line = s.nextLine();
System.out.println("line="+line);

s.close();

编辑:上述解决方案有一些缺点。首先,它不会关闭内部输入流,因此存在泄漏。其次,它取决于字符集是单字节的。它不适用于多字节字符集(即 UTF-8)。为了解决这些问题,我们可以使用 aReadableByteChannel代替:

Scanner s = new Scanner(new ReadableByteChannel(){

    private InputStream is = new SlowInputStream();
    boolean isopen = true;

    public int read(ByteBuffer arg0) throws IOException {
        int i = is.read();
        if(i>=0){
            arg0.put((byte)i);
            return 1;
        } else return -1;
    }

    public void close() throws IOException {
        isopen=false;
        is.close();
    }

    public boolean isOpen() {
        return isopen;
    }

});

编辑:感谢您的评论,我已经修复了文本中的错误,并对这个问题给出了更好的解释。

于 2012-11-29T01:54:53.203 回答