一、字節輸入流
java.io.InputStream 抽象類是表示字節輸入流的所有類的超類,可以讀取字節信息到內存中。
它定義了字節輸入流的基本共性功能方法。
共性方法:
public abstract int read() : 從輸入流讀取數據的下一個字節。返回 0 到 255 范圍內的 int 字節值。
public int read(byte[] b) : 從此輸入流中將最多 b.length 個字節的數據讀入一個 byte 數組中,否則以整數形式返回實際讀取的字節數。
public int read(byte[] b, int off, int len) :一次讀取多個字節,返回本次實際讀取字節數,讀取的字節存到b數組中,從[off]開始存儲,一次最多讀取len個字節
public void close() :關閉此輸入流並釋放與此流相關聯的任何系統資源。
如果 read() 方法到達流末尾沒有可用的字節,返回-1。
注意:close 方法,當完成流的操作時,必須調用此方法,釋放系統資源。
InputStream 的子類
深色的為節點流,淺色的為處理流。
二、FileInputStream 類
java.io.FileInputStream 類是文件輸入流,從文件中讀取數據,讀取到內存中使用。
1、構造方法
FileInputStream(File file) : 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的 File對象 file命名。
FileInputStream(String name) : 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的路徑名 name命名。
參數:讀取文件的數據源
String name:文件的路徑
File file:文件對象
構造方法的作用:
① 會創建一個FileInputStream對象
② 會把FileInputStream對象指定構造方法中要讀取的文件
讀取數據的原理(硬盤--> 內存)
java程序-->JVM-->OS-->OS讀取數據的方法-->讀取文件
字節輸入流的使用步驟【重要】:
① 創建FileInputStream對象,構造方法中綁定要讀取的數據源
② 使用FileInputStream對象中的方法read,讀取文件
③ 釋放資源
2、讀取字節數據
(1)讀取字節: read 方法,每次可以讀取一個字節的數據,提升為int類型,讀取到文件末尾,返回 -1 ,代碼使用演示:
1 public static void main(String[] args) throws IOException { 2 //1.創建FileInputStream對象,構造方法中綁定要讀取的數據源
3 FileInputStream fis = new FileInputStream("E:\\c.txt"); 4 //2.使用FileInputStream對象中的方法read,讀取文件 5 //int read()讀取文件中的一個字節並返回,讀取到文件的末尾返回-1
6 /*
7 發現以上讀取文件是一個重復的過程,所以可以使用循環優化 8 不知道文件中有多少字節,使用while循環 9 while循環結束條件,讀取到-1的時候結束 10
11 布爾表達式(len = fis.read())!=-1 12 1.fis.read():讀取一個字節 13 2.len = fis.read():把讀取到的字節賦值給變量len 14 3.(len = fis.read())!=-1:判斷變量len是否不等於-1 15 */
16 int len = 0; //記錄讀取到的字節
17 while((len = fis.read())!=-1){ 18 System.out.print(len);//abc
19 } 20
21 //3.釋放資源
22 fis.close(); 23 }
(2)使用字節數組讀取: read(byte[] b) ,每次讀取b的長度個字節到數組中,返回讀取到的有效字節個數,讀取到末尾時,返回 -1 。
int read(byte[] b) 從輸入流中讀取一定數量的字節,並將其存儲在緩沖區數組 b 中。
明確兩件事情:
a. 方法的參數byte[]的作用?
起到緩沖作用,存儲每次讀取到的多個字節,數組的長度一把定義為1024(1kb)或者1024的整數倍
b.方法的返回值int是什么?
每次讀取的有效字節個數
Demo :
1 public static void main(String[] args) throws IOException { 2 //創建FileInputStream對象,構造方法中綁定要讀取的數據源
3 FileInputStream fis = new FileInputStream("E:\\b.txt"); 4 //使用FileInputStream對象中的方法read讀取文件 5 //int read(byte[] b) 從輸入流中讀取一定數量的字節,並將其存儲在緩沖區數組 b 中。
6 /*
7 發現以上讀取時一個重復的過程,可以使用循環優化 8 不知道文件中有多少字節,所以使用while循環 9 while循環結束的條件,讀取到-1結束 10 */
11 byte[] bytes = new byte[1024];//存儲讀取到的多個字節
12 int len = 0; //記錄每次讀取的有效字節個數
13 while((len = fis.read(bytes))!=-1){ 14 //String(byte[] bytes, int offset, int length) 把字節數組的一部分轉換為字符串 offset:數組的開始索引 length:轉換的字節個數
15 System.out.println(new String(bytes,0,len)); 16 } 17
18 //釋放資源
19 fis.close(); 20 }
Tips:使用數組讀取,每次讀取多個字節,減少了系統間的IO操作次數,從而提高了讀寫的效率,建議開發中使用。
字節流讀取文件的原理:
三、復制文件案例
復制文件原理圖解:
文件復制的步驟:
1. 創建一個字節輸入流對象,構造方法中綁定要讀取的數據源
2. 創建一個字節輸出流對象,構造方法中綁定要寫入的目的地
3. 使用字節輸入流對象中的方法read讀取文件
4. 使用字節輸出流中的方法write,把讀取到的字節寫入到目的地的文件中
5. 釋放資源
代碼實現:
1 public static void main(String[] args) throws IOException { 2 //1.創建一個字節輸入流對象,構造方法中綁定要讀取的數據源
3 FileInputStream fis = new FileInputStream("c:\\1.jpg"); 4 //2.創建一個字節輸出流對象,構造方法中綁定要寫入的目的地
5 FileOutputStream fos = new FileOutputStream("d:\\1.jpg"); 6 //一次讀取一個字節寫入一個字節的方式 7 //3.使用字節輸入流對象中的方法read讀取文件
8 /*int len = 0; 9 while((len = fis.read())!=-1){ 10 //4.使用字節輸出流中的方法write,把讀取到的字節寫入到目的地的文件中 11 fos.write(len); 12 }*/
13
14 //使用數組緩沖讀取多個字節,寫入多個字節
15 byte[] bytes = new byte[1024]; 16 //3.使用字節輸入流對象中的方法read讀取文件
17 int len = 0;//每次讀取的有效字節個數
18 while((len = fis.read(bytes))!=-1){ 19 //4.使用字節輸出流中的方法write,把讀取到的字節寫入到目的地的文件中
20 fos.write(bytes,0,len); 21 } 22
23 //5.釋放資源(先關寫的,后關閉讀的;如果寫完了,肯定讀取完畢了)
24 fos.close(); 25 fis.close(); 26 }
注意:流的關閉原則,先開后關,后開先關。