File 裡面的flush()和close()
阿新 • • 發佈:2019-02-14
前天專案組遇到檔案上傳,對記憶體加大的問題。特意看了看相關知識,也對這個有一定的瞭解
try { FileInputStream fis=new FileInputStream(new File("/home/saas/maven/maven.zip")); BufferedInputStream bis=new BufferedInputStream(fis); FileOutputStream fos=new FileOutputStream(new File("/home/saas/bb.sh")); byte[] buffer=new byte[1024*1024*1024];//這是自定義java緩衝區 int len=0; while((len=bis.read(buffer))>0){// fos.write(buffer, 0, len);//貌似直接就呼叫了io的底層 // fos.flush(); System.out.println("複製了 1024*1024*1024 Byte"); } fis.close(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
首先這裡個FileInputtream裡面的close方法和flush()方法 不呼叫也會將檔案,這個檔案也會被複製成功,並且資料對。原理是這樣的,因為fos裡面直接呼叫的本地方法,將資料寫入檔案,所以不關掉也能成功,但不關掉會造成記憶體不能回收,有可能造成記憶體洩漏什麼的
其次,BufferedInputream和BufferedOutputStream 都是提供快取,可以看到裡面有個快取陣列buf[] 預設是8092位元組。以下是原始碼
/** * Writes the specified byte to this buffered output stream. * * @param b the byte to be written. * @exception IOException if an I/O error occurs. */ public synchronized void write(int b) throws IOException { if (count >= buf.length) { flushBuffer(); } buf[count++] = (byte)b; }
這裡首先判斷一下,當前是緩衝區是否已經滿了,如果沒滿,就繼續寫,如果滿了,就會flushBuffer,flushBuffer其實就是將呼叫本地方法,將位元組數組裡的資料寫入檔案裡面,以下是原始碼
/** Flush the internal buffer */
private void flushBuffer() throws IOException {
if (count > 0) {
out.write(buf, 0, count);
count = 0;
}
}
當你呼叫BufferOutputStream 的write.如果傳入的是FileInputStream的話,BufferOutputSream 裡面的out就會指向FileInputStream。這裡使用了裝飾模式。
另外可以看到原始碼,FileInputStream裡面的flush是繼承OutputStream的,而OutputStream裡的flush是個空的方法,什麼都沒幹