用BufferedInputStream包装后对原始InputStream的影响

时间:2014-01-22 10:08:32

标签: java inputstream bufferedinputstream

假设我有一个接受InputStream的方法。

此方法需要使用BufferedInputStream包装此InputStream以使用其标记和重置功能。但是,传入的InputStream可能仍然由方法的调用者使用。

public static void foo(InputStream is) throws Exception {
    BufferedInputStream bis = new BufferedInputStream(is);
    int b = bis.read();
}

public static void main(String[] args) {


    try {
        InputStream is = new FileInputStream(someFile);
        foo(is);
        int b = is.read(); // return -1
    }catch (Exception e) {
        e.printStackTrace();
    }
}

我的问题是:当读取(或初始化)BufferedInputStream时,原始InputStream究竟发生了什么?

我的假设是,如果读取BufferedInputStream,原始InputStream也将向前移动。但是,在调试我的代码之后,我发现InputStream在读取时将返回-1。

如果在这样的过程之后原始的InputStream不可读,我应该如何实现我的目的:

InputStream is;
foo(is);               // Method only take in generic InputStream object
                       // Processing of the passed in InputStream object require mark and reset functionality
int b = is.read();     // Return the next byte after the last byte that is read by foo()

编辑: 我想我要求的是非常通用的,因此需要做很多工作。至于我正在做什么,我实际上并不需要满分和标记。重置功能所以我找到了一个小工作。但是,我会在这里留下问题的第二部分,所以请随意尝试这个问题:)。

5 个答案:

答案 0 :(得分:1)

BufferedInputStream的默认bufferSize是8192,所以当你从BufferedInputStream读取时,它会尝试填充它的缓冲区。因此,如果您必须读取InputStream字节而不是bufferSize,那么InputStream的完整内容将被读取到缓冲区,因此您获得-1后阅读BufferedInputStream

查看BufferedInputStream源代码:http://www.docjar.com/html/api/java/io/BufferedInputStream.java.html

答案 1 :(得分:0)

http://docs.oracle.com/javase/7/docs/api/java/io/BufferedInputStream.html#BufferedInputStream%28java.io.InputStream%29

看起来BufferedInputStream使用InputStream来执行使用数据流执行的操作。 Buffered类只是实现了一个供内部使用的缓冲区数组。

不确定你可以使用什么,除了复制InputStream以便你有第二个要调用的对象。

答案 2 :(得分:0)

BufferedInputStream将批量预加载基础InputStream的数据,这将触发基础InputStream位置的相应移动。如果缓冲区大小足以一次性消耗基础流中的所有数据,您可能会观察到您描述的行为。

答案 3 :(得分:0)

两件事:

  1. 任何接受流作为输入参数的API都可能会使用该流,因此调用者期望流保持任何类型的可用状态是不合理的。也许最好让java流类以某种方式强制执行单一所有权以使其更清晰。

  2. 作为一种特殊情况,BufferedInputStream将使用它“包装”的底层流,因为它实现了(有限形式的)标记并通过缓冲块读取来重置,正如其他人所指出的那样。

答案 4 :(得分:0)

private static class MybufferedInputStream extends BufferedInputStream {
    public MybufferedInputStream(InputStream in) {
        super(in);
    }

    public int getBufferSize(){
        int i=0;
        for (Byte byte1 : super.buf) {
            if (byte1!=0) {
                i++;
            }
        }
        return i;
    }
}

然后你可以在read()之后调用getBufferSize()来查看小文件和更大文件之间的区别。