概念
I/O(Input/Output)流:內存於存儲設備(硬盤等)之間傳輸數據的通道,程序允許通過流的方式於輸入輸出設備進行數據傳輸。流位於 java.io 包下
按方向分類:
- 輸入流:將<存儲設備>中的內容讀入到<內存>中
- 輸出流:將<內存>中的內容寫入到<存儲設備>中
按傳輸數據的單位分類:
- 字節流:以字節爲單位,可以讀寫所有數據
- 字符流:以字符爲單位,只能讀寫文本數據
按功能分類:
- 節點流:具有實際傳輸數據的讀寫功能
- 過濾流:在節點流的基礎之上增強功能
字節流
在 jdk 中,提供了兩個抽象類 InputStream 和 OutputStream ,它們是字節流的頂級父類。
InputStream的常用方法
方法聲明 | 功能描述 |
---|---|
int read() | 從輸入流讀取一個8位字節,轉換爲0~255之間的整數,並返回這一整數,當沒有可用字節時,返回-1 |
int read(byte[] b) | 從輸入流讀取若干字節,保存在參數b指定的字節數組中,返回的整數表示讀取字節的數目 |
int read(byte[] b,int off,int len) | 從輸入流讀取若干字節,保存在參數b指定的字節數組中,off指定字節數組開始保存數據的起始下標,len表示讀取的字節數目 |
void close() | 關閉此輸入流並釋放該流關聯的所有系統資源 |
OutputStream的常用方法
方法聲明 | 功能描述 |
---|---|
void write(int b) | 將指定的字節寫入此輸出流 |
void write(byte[] b) | 把參數b指定的字節數組的所有字節寫到輸出流 |
void write(byte[] b,int off,int len) | 將指定byte數組中從偏移量off開始的len個字節寫入輸出流 |
void flush() | 刷新此輸出流並強制寫出所有緩衝的輸出字節 |
void close() | 關閉此輸出流並釋放該流關聯的所有系統資源 |
面向文件的讀寫操作
-
FileOutputStream
構造方法:
FileOutputStream(String name) 創建文件輸出流以指定的名稱寫入文件。 參數可以寫稱盤符,例如 “F:\\a.txt” 不需要指明往哪個文件寫入,每刷新一次,將首先覆蓋原來的數據,再寫入
FileOutputStream(String name, boolean append) 創建文件輸出流以指定的名稱寫入文件。第二個參數是布爾類型的參數,意思是,是否追加, 如果爲true,在原始數據後面寫入,如果爲false或者不寫,即爲不追加,任然是覆蓋原來的數據再寫入
-
public void write(byte[] b) 一次寫多個字節,將b數組中所有字節,寫入輸出流
public static void main(String[] args) throws Exception { //字節輸出流,如果裏面沒有此盤符,會出錯 //但是,如果在此盤符下沒有此文件,他會先創建文件,再寫入 /* * 絕對路徑:D:\\Development\\IdeaProjects\\IO\\Files\\a.txt * 相對路徑:Files\\a.txt 相對於此項目的位置,與上一種形式等價 * */ FileOutputStream fileOutputStream = new FileOutputStream("Files\\a.txt",true); fileOutputStream.write(65);//一次輸出一個字節 fileOutputStream.write(66); fileOutputStream.write('C'); byte[] bytes = new byte[]{65,66,67,68,69}; fileOutputStream.write(bytes);//一次輸出一組字節 //輸出一組字節,從下標1開始,輸出3個 fileOutputStream.write(bytes,1,3); } -------------------------------------------------- 但是,F:\\a.txt 這個路徑是個絕對路徑,屬於硬編碼,不符合實際, 所以我們使用相對路徑,就是相對於程序本身項目的位置,項目的根, "a.txt" 就使用這種方式
-
-
FileInputStream
-
public void read(byte[] b) 從流中讀取多個字節,將讀到的內容存入b數組,返回實際讀到的字節數
public static void main(String[] args) throws IOException { //字節輸入流 FileInputStream fis = new FileInputStream("Files\\a.txt"); //先寫一個死循環,在裏面讀,再判斷,因爲沒有可用字節時 //返回 -1 所以裏面判斷,當返回的整數爲 -1 時,就跳出循環, //實際上就是讀取完成 while (true) { //一次讀取一個字節 int read = fis.read(); if(read == -1) { break; } System.out.println((char) read); } } 但是這種方式也不好,每讀取一個字節,就要讀一次磁盤,對於硬盤也是有損傷的 ------------------------------------- //一次讀取一組字節 //創建一個長度爲4的數組,作爲讀取時的緩存 //也可以寫成 1024 * 1024 byte[] bytes = new byte[4]; while (true) { //每讀取一次,填滿數組,最後一次可能填不滿 int i = fis.read(bytes); if(i == -1) { break; } //根據讀取字節的個數,決定打印次數 for (int j = 0; j < i; j++) { System.out.print((char) bytes[j] + "\t"); } System.out.println(); } } 這種方式可以減少訪問硬盤的次數
-