2014-01-22 12 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()看到一個小文件和較大的文件之間的差異。

相關問題