2014-01-22 11 views
5

假设我有一个接受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() 

编辑: 我想我要问的是很普通的,因此需要大量的工作的。至于我在做什么,其实我并不需要重新设置标记&,所以我找到了一个小小的解决方法。但是,我将在这里留下问题的第二部分,所以请随时尝试此问题:)。

回答

1

BufferedInputStream的默认缓冲区大小为8192,因此当您从BufferedInputStream读取时,它会尝试填充缓冲区。所以,如果你有从InputStream少读取字节,比bufferSize,那么你InputStream的全部内容读入缓冲区,所以你得到-1从BufferedInputStream

看完之后有一个看看BufferedInputStream源代码:从底层InputStream分批http://www.docjar.com/html/api/java/io/BufferedInputStream.java.html

0
BufferedInputStream

将预加载的数据,这将触发底层InputStream位置的各自的举动。如果缓冲区大小足以一次性使用来自底层流的所有数据,则可能会观察到您描述的行为。

0

两件事情:

  1. 接受作为输入参数很可能将使用流,所以它是不合理的调用者期望流保持在任何一种可用状态的数据流的任何API 。也许对于java流类来说,强化单一所有权以某种方式来实现更清晰会更好。正如其他人指出的那样,BufferedInputStream将使用其“包装”的基础流,因为它实现(有限形式)标记并通过缓存块读取进行重置。

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; 
    } 
} 

,那么你可以阅读()后调用getBufferSize()看到一个小文件和较大的文件之间的差异。

相关问题