目錄
2.OutputStream的緩存器(自定義數組)與BufferedOutputStream中的緩存器(數組)區別
要介紹BufferedOutputStream的坑,我們先了解一下OutputStream類
抽象類OutputStream類有三個write方法
public abstract void write(int b) public void write(byte b[]) public void write(byte b[], int off, int len) |
由上面我們可以看出第一個write方法是讓子類覆蓋的,而第二個人write(byte b[])方法源代碼如下
public void write(byte b[]) throws IOException { write(b, 0, b.length); } |
所以可見最後處理還是調用第三個方法write(byte b[],int off,int len)
1.實戰:複製文件
public class TestCopyFile { public static void main(String[] args) throws IOException { String filePath = "F:/123.png"; String filePath2 = "F:/abc.png"; File file = new File(filePath); File file2 = new File(filePath2); copyFile(file, file2); } 原文:https://blog.csdn.net/lan861698789/article/details/81380409 public static void copyFile(File oldFile, File newFile) { InputStream inputStream = null; BufferedInputStream bufferedInputStream = null; OutputStream outputStream = null; BufferedOutputStream bufferedOutputStream = null; try { inputStream = new FileInputStream(oldFile); bufferedInputStream = new BufferedInputStream(inputStream); outputStream = new FileOutputStream(newFile); bufferedOutputStream = new BufferedOutputStream(outputStream);
byte[] b = new byte[1024]; // 1代表一次最多讀取1KB的內容 int length = 0; // 代表實際讀取的字節數 while ((length = bufferedInputStream.read(b)) != -1) { bufferedOutputStream.write(b, 0, length); } bufferedOutputStream.flush();// 緩衝區的內容寫入到文件 } catch (Exception e) { e.printStackTrace(); } finally { //......省略 } } } |
注意:上面黃顏色1地方的b數組,不能大於8kb,否則buffer就沒意義了。這就是使用BufferedOutputStream的弊端。
2.OutputStream的緩存器(自定義數組)與BufferedOutputStream中的緩存器(數組)區別
看BufferedInputStream源碼:
public class BufferedOutputStream extends FilterOutputStream { protected byte buf[];// 這兒定義了一個byte[]數組,用來充當緩存器 protected int count; // 這個變量是重點,他就是用來記錄當前緩存器中的字節數量的 public BufferedOutputStream(OutputStream out) {// 我們初始化創建一個對象的時候給了這個buf這個數組8192個字節.8KB this(out, 8192); }
public BufferedOutputStream(OutputStream out, int size) { super(out); buf = new byte[size]; // 這兒創建一個給定大小的數組對象來充當緩存器 }
public synchronized void write(int b) throws IOException { if (count >= buf.length) { flushBuffer(); } buf[count++] = (byte) b; } 原文:https://blog.csdn.net/lan861698789/article/details/81380409 // 該方法是重點 public synchronized void write(byte b[], int off, int len) throws IOException { //如果傳進來的數組長度大於buf 數組的長度,則直接調用OutputStream對象的write方法。 if (len >= buf.length) { flushBuffer(); out.write(b, off, len); return; } //驗證BufferedOutputStream 類中buf剩下的空間能否裝得下傳進來的數組。如果不能則先將當前buf數組中數據寫入底層io流中 if (len > buf.length - count) { flushBuffer(); } //該處是重點,如果在當前BufferedOutputStream 類中buf數組沒有滿,則將傳進來的數組複製到當前類對象buf數組中,同時更新count的值。 System.arraycopy(b, off, buf, count, len); count += len; } //調用flushBuffer方法也就是將不滿8192個字節數組中的數據發送出去。同時將count置零。 private void flushBuffer() throws IOException { if (count > 0) { out.write(buf, 0, count); count = 0; } } // 強制將buf數據中未滿8192個字節的數據寫入底層io中。 public synchronized void flush() throws IOException { flushBuffer(); out.flush(); } } |
結論:
OutputStream的緩存器(數組)與BufferedOutputStream中類的緩存器(數組)本質是一樣的。
區別:
優點:
只是BufferedOutputStream類中將要寫入到底層io流中的數據先湊個整,然後再一起寫入底層io流中,這樣就大大節省了io操作,大大提高了io利用率,寫一次io是很費資源的。
原文:https://blog.csdn.net/lan861698789/article/details/81380409
缺點:
1.如果要寫入的size沒有buf大,然後如果buf沒有滿,則會把當前數組的值複製到buf裏面,多了很多複製的操作。
2.如果要寫入的size大於buf,則直接將全部數據寫入IO。那麼感覺使用BufferedOutputStream的意義就沒有了。感覺只有當要寫入的size遠小於buf時候,纔有意義。
2.這樣也出現了一個問題,假設向硬盤中寫入一個文件,文件最後數據比默認值8192個字節小,則BufferOutputStream就不會將這些數據寫入底層io流中,造成文件缺失,因此就需要在close()前調用flush()方法,強制將還沒有裝滿buf數組的數據寫入底層io中。
原文:https://blog.csdn.net/lan861698789/article/details/81380409
總結:建議使用outputStream,然後自定義數組來存放緩存。