最近又退回到java EE的學習,這篇博客就來講解一下字節流中最重要的兩個類FileInputStream和FileOutputStream的用法:
- FileInputStream:全稱是文件字節輸入流,屬於字節流,作用是按字節讀取的方式讀取文件,繼承InputStream類;
- FileOutputStream:全稱是文件字節輸出流,屬於字節流,作用是以字節的方式向文件寫入內容,繼承OutputStream類;
一、FileInputStream用法:
創建FileInputStream類對象用兩種方式,一種是直接在構造方法中傳入表示文件位置的字符串;第二種就是創建一個表示文件位置的File對象,然后在FileInptuStream的構造方法中傳入這個File對象。創建FileInputStream對象會拋出一個FileNotFoundException異常。下面的代碼演示了兩種創建方式:
對象創建完成,就可以調用FileInputStream類中的方法讀取文件中的內容了。讀取文件中的內容的方法叫做read方法,這個方法繼承自父類,在子類中有多個同名的重載方法。
1、使用read()方法一次讀取一個字節
使用read()方法讀取文件,這個方法將會讀取文件中的一個字節,並將讀取到的字節大小返回,然后跳到下一個字節;若讀到了文件結尾,則返回-1。如下代碼演示了這個方法:
上面代碼先創建了一個FileInputStream對象,然后使用read方法讀取文件中的內容,接收返回值並輸出,這一過程重復兩次。讀取的文件中,只用一個字母a。而運行結果如右圖:
第一次讀取到的字節大小是97,這正是字符‘a’的ASCII碼大小,而讀取完第一個字節后跳到下一個字節再次讀取,而此時文件內容已經結束,所以返回-1。read方法和close方法都會拋出一個IOException,而它是ClassNotFoundException的父類,所以拋出IOException的同時也算拋出了ClassNotFoundException。
為了將文件中的內容讀完,我們可以使用循環,判斷是read的返回值是否為-1,若不為,則表示文件未讀取完。而若是-1,則表示讀取到了文件的最后一個字節,結束循環,文件讀取完畢,代碼如下:
2、使用read( byte[] bytes )方法一次讀取多個字節
使用read( byte[] bytes)方法讀取文件,傳入的是一個byte類型的數組,這個方法將一次讀取多個字節(一次讀取的字節個數取決於byte數組的大小),將讀取到的字節放入傳入的byte數組中,並返回讀取到的字節個數,若讀取到文件末尾,返回-1。如下是使用read( byte[] bytes)方法讀取文件的代碼:
上面的代碼創建了一個大小為1024的byte數組(推薦為1024或者1024的倍數),並使用read( byte[] bytes)方法來一次讀取多個字節,返回的是讀取到的字節個數,文件內容以及程序運行結果如下:
因為byte數組大小1024個字節,所以一次就將文件中全部字節讀取完,並返回字節個數26。而第二次讀取時,已經到達了文件末尾,所以並未讀取到字節,返回-1。為了方便查看,上面的代碼使用了String類的一個構造方法,將一個byte數組轉換為字符串,轉換byte數組中從0位置開始,后面的len個單位。
而此方法也可以和循環配合使用,一次性將文件中的內容讀取完畢。代碼如下:
二、FileOutputStream的用法
FileOutputStream的使用方式與FileInputStream類似,創建FileInputStream對象也是傳入一個表示文件位置的字符串,可以是相對位置,也可以是絕對位置。FileOutputStream類是用來向文件中寫入字節的,如果寫入的文件不存在,將會創建這個文件(前提是路徑存在)。FileInputStream對象通過調用write方法向文件中寫入,寫入的方式也和read方法類似,有幾種不同的形式,下面就來看看。
1、使用 write(int b) 方法向文件中寫入一個字節
使用 write(int b) 方法可以向文件中寫入一個字節,寫入的字節大小就是方法的參數。write方法會拋出一個IOException異常。下面代碼演示如何調用這個方法,向文件中寫入大小為97的字節,也就是‘a’的ASCII碼:
方法執行完畢,打開文件,查看文件中的內容是一個a,因為記事本等文本編輯器會自動將字節轉為字符,方便查看,文件截圖如下:
2、使用 write(byte[] bytes) 方法向文件中寫入多個字節
使用write(byte[] bytes)方法,參數為一個字節數組,可以向文件中寫入多個字節。我們先將需要寫入文件的字節存入字節數組中,再將字節數組作為參數傳入write方法,就可以實現同時寫入多個字節:
結果如下:
3、使用 write(byte[] bytes,int off,int len) 方法將字節數組中的部分內容寫入文件
write方法還可以擴展,有時我們傳入一個字節數組作為write方法的參數,但是我們並不想將字節數組中的全部內容寫入文件,只想寫入其中的一部分,這時則可以使用write(byte[] bytes,int off,int len) 方法,方法的第一個參數為字節數組,第二個參數為字節數組中寫入文件部分的起始下標,第三個參數是從起始下標開始,要寫入的個數,測試代碼如下:
上面調用write(byte[] bytes,int off,int len) 方法,從字節數組中下標為2的元素開始,寫入兩個元素,也就是字節67與68,這兩個字節對應的字符為C和D:
三、FIleInputStream與FileOutputStream綜合案例——復制文件
我們知道,在計算機中,所有的東西都是由字節(也就是二進制數據)組成,所以我們可以通過這兩個字節流類實現文件的復制。,下面使用這兩個類實現一個文件的復制,這里將復制一張照片,復制方法:使用FileInputStream類讀取文件,然后將讀取到的字節通過FileOutputStream類寫入到另外一個位置,這樣就實現了復制。我們可以使用read()方法以及write(int b)方法一次復制一個字節,但是這樣速度太慢,下面的代碼將使用read(byte[] bytes)以及write(byte[] bytes)方法,一次復制多個字節,提高效率。下面是代碼: