BufferedOutputStream和ByteArrayOutputStream區別


結論:當你資源不足夠用時,選擇BufferedOutputStream是最佳的選擇, 當你選擇快速完成一個作業時,可以選擇ByteArrayOutputStream之類的輸出流

1.BufferedOutputStream實現原理:

tip:BufferedOutputStream 默認是new byte[8192]字節,ByteArrayOutputStream默認是new byte[32]字節

BufferedOutputStream會首先創建一個默認的容器量, capacity = 8192B = 8KB, 每次在寫的時候都會去比對capacity是否還夠用, 如果不夠用的時候, 就flushBuffer(), 把buf中的數據寫入對應的outputStream中, 然后將buf清空, 一直這樣等到把內容寫完. 在這過程中主要起到了一個數據緩沖的功能. 

public synchronized void write(byte b[], int off, int len) throws IOException {  
      // 在這判斷需要寫的數據長度是否已經超出容器的長度了,如果超出則直接寫到相應的outputStream中,並清空緩沖區  
      if (len >= buf.length) {  
          flushBuffer();  
          out.write(b, off, len);  
          return;  
      }  
      // 判斷緩沖區剩余的容量是否還夠寫入當前len的內容,如果不夠則清空緩沖區  
      if (len > buf.length - count) {  
          flushBuffer();  
      }  
      // 將要寫的數據先放入內存中,等待數據達到了緩沖區的長度后,再寫到相應的outputStream中  
      System.arraycopy(b, off, buf, count, len);  
      count += len;  
    }  
private void flushBuffer() throws IOException {  
       if (count > 0) {  
          // 把寫入內存中的數據寫到構造方法里傳入的OutputStream句柄里, 並把容量大小清楚  
    out.write(buf, 0, count);  
    count = 0;  
       }  
   }  

2.ByteArrayOutputStream實現原理:

也會首先創建一個默認的容器量, capacity = 32 = 32byte, 每次在寫的時候都會去比對capacity是否還夠用, 如果不夠用的時候, 就重新創建buf的容量, 一直等到內容寫完, 這些數據都會一直處於內存中. 

public synchronized void write(byte b[], int off, int len) {  
      if ((off < 0) || (off > b.length) || (len < 0) ||  
            ((off + len) > b.length) || ((off + len) < 0)) {  
          throw new IndexOutOfBoundsException();  
      } else if (len == 0) {  
          return;  
      }  
        // 不斷對自己的容量進行相加  
        int newcount = count + len;  
        // 如果新的容量大小已經超過了現有的大小時,則重新開辟新的內存區域來保存當前的數據  
        if (newcount > buf.length) {  
            buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));  
        }  
        System.arraycopy(b, off, buf, count, len);  
        count = newcount;  
    }  

 

應用:

public static <T extends Serializable> T clone(T obj) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
    //個人感覺用Buffered系列,還需要傳入一個指定容器,比如文件對應的寫出流,相比,ByteArray臨時處理一些小數據,很方便,數據直接全量存儲在內存中(基於內存的流),
    //獲取內存中的數據,直接toByteArray()即可 ObjectOutputStream oos
= new ObjectOutputStream(bout); oos.writeObject(obj);//將obj流數據寫入內存 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bin); return (T) ois.readObject(); // 說明:調用ByteArrayInputStream或ByteArrayOutputStream對象的close方法沒有任何意義 // 基於內存的流只要垃圾回收器清理對象就能夠釋放資源,這一點不同於對外部資源(如文件流)的釋放 }

 

 轉https://www.iteye.com/blog/z276356445t-1955400


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM