Java知識點——IO流

  • 2020 年 3 月 18 日
  • 筆記

IO流

1.1 什麼是IO流

I input 輸入流 read 讀取數據 O output 輸出流 write 寫入數據

一般情況下都是按照當前程式使用的記憶體為參照物來考慮數據的走向問題。 文件操作為例 從記憶體中保存數據到硬碟 output 從硬碟中讀取數據到記憶體 input0

文件操作為例 1GB完整的文件拷貝過程,要遠遠高於1GB散文件的拷貝過程。 1. 打開文件,關閉文件消耗資源較少 2. 1GB散文件就需要不斷的打開,關閉資源 操作時間的消耗和打開文件,關閉文件或者說打開硬碟,關閉硬碟有直接關係

IO流基類

InputStream 輸入流基類 read

OutputStream 輸出流基類 write

1.2 IO流分類

流向分類  輸入輸出

文件操作處理單元分類  位元組流和字元流

FileInputStream  文件操作輸入位元組流 FileOutputStream  文件操作輸出位元組流

FileReader  文件操作輸入字元流 FileWriter  文件操作輸出字元流

1.3 文件操作位元組流

1.3.1 文件操作輸入位元組流
FileInputStream 文件操作輸入位元組流    Constructor 構造方法  	FileInputStream(File file);  		這裡是根據提供的File類對象創建對應的文件操作輸入位元組流。    	FileInputStream(String pathName);  		這裡是根據提供的String類型文件路徑,創建對應的文件操作輸入位元組流。  	都會拋出異常:  		FileNotFoundException 文件未找到異常。    Method 成員方法  	int read();  		從文件中讀取一個位元組數據返回到方法外。  		雖然返回值是一個int類型,但是在整個int類型當中存儲的數據是一個byte類型,有  		且只有低8位數據有效    	int read(byte[] buf);  		讀取文件的內容是存儲在byte類型數組中,返回值是讀取到的位元組個數    	int read(byte[] buf, int offset, int count);  		讀取文件的內容是存儲在byte類型數組中,要求從byte數組offset位置開始,到  		count長度結束,返回值是讀取到的位元組個數    	以上三個方法如果讀取到文件末尾,返回值都是 -1 EOF End Of File  	而且以上方法都要異常拋出  		IOException IO異常
1.3.2 使用演示
 	import java.io.File;      import java.io.FileInputStream;      import java.io.IOException;        /*       * 文件操作輸入位元組流       * 	1. 確認讀取哪一個文件       * 	2. 創建對應文件的FileInputStream       * 	3. 讀取數據       * 	4. 關閉資源 【重點】       */      public class Demo1 {      	public static void main(String[] args) {      		long start = System.currentTimeMillis();        		readTest1();        		long end = System.currentTimeMillis();      		System.out.println("Time : " + (end - start));      	}        	public static void readTest2() {      		// 1. 確定操作文件      		File file = new File("C:\aaa\1.txt");        		// 2. 位元組輸入流讀取文件對象      		FileInputStream fileInputStream = null;        		try {      			// 3. 根據File類對象創建對應的位元組輸入流      			fileInputStream = new FileInputStream(file);        			// 4. 準備一個8KB位元組緩衝數組      			byte[] buf = new byte[1024 * 8];      			int length = -1;        			// 5. 讀取數據      			while ((length = fileInputStream.read(buf)) != -1) {      				System.out.println(new String(buf, 0, length));      			}        		} catch (IOException e) {      			// TODO Auto-generated catch block      			e.printStackTrace();      		} finally {      			// 在finally程式碼塊中關閉資源      			if (fileInputStream != null) {      				try {      					fileInputStream.close();      				} catch (IOException e) {      					// TODO Auto-generated catch block      					e.printStackTrace();      				}      			}      		}      	}        	/*      	 * low!!!      	 */      	public static void readTest1() {      		// 1. 確定操作文件      		File file = new File("C:\aaa\1.txt");        		// 2. 位元組輸入流讀取文件對象      		FileInputStream fileInputStream = null;        		try {      			// 3. 根據File類對象創建對應的位元組輸入流      			fileInputStream = new FileInputStream(file);        			// 4. 讀取文件      			int content = -1;        			while ((content = fileInputStream.read()) != -1) {      				System.out.println((char)content);      			}      		} catch (IOException e) {      			// TODO Auto-generated catch block      			e.printStackTrace();      		} finally {      			// 用於處理程式碼中使用到資源,無法發生什麼樣的錯誤,finally中的程式碼一定會執行      			// 這裡發現fileInputStream不是null,證明已經打開了文件資源,關閉資源,捕獲異常      			if (fileInputStream != null) {      				try {      					fileInputStream.close();      				} catch (IOException e) {      					// TODO Auto-generated catch block      					e.printStackTrace();      				}      			}      		}      	}      }
1.3.3 文件讀取使用緩衝和非緩衝差距

記憶體的運作速度看做是火箭 硬碟就是一個自行車 以上程式碼中,使用緩衝之後,從硬碟中一口氣讀取8KB數據存儲在記憶體中,供程式使用。

8KB固態硬碟,4KB對齊。固態硬碟中每一個扇區都是4KB。緩衝這裡是要求CPU讀取兩個4KB數據,對於CPU而言沒有太多壓力。 如果是一個位元組一個位元組讀取,CPU取出4KB數據,結果有4095無效。

1.3.4 文件操作輸出位元組流

FileOutputStream 文件操作輸出位元組流

Constructor 構造方法:

FileOutputStream(File file); 根據File類對象創建對應的文件輸出位元組流對象

FileOutputStream(String pathName); 根據String類型文件路徑創建對應的文件輸出位元組流對象

以上兩個構造方法,創建的FileOutputStream是刪除寫/清空寫操作,會將原文件中的內容全部刪除之後,寫入數據。

FileOutputStream(File file, boolean append); 根據File類對象創建對應的文件輸出位元組流對象。創建對象時給予append參數為 true,表示追加寫。

FileOutputStream(String pathName, boolean append); 根據String類型文件路徑創建對應的文件輸出位元組流對象,創建對象時給予append參數為true,表示追加寫。

FileOutputStream構造方法是擁有創建文件的內容,如果文件存在,不創建,文件不存在且路徑正確,創建對應文件。否則拋出異常FileNotFoundException

Method 成員方法:

void write(int b); 寫入一個位元組數據到當前文件中,參數是int類型,但是有且只會操作對應的低八位數據

void write(byte[] buf); 寫入位元組數組中的內容到文件中

void write(byte[] buf, int offset, int length); 寫入位元組數組中的內容到文件中,從指定的offset開始,到指定長度length

以上方法會拋出異常:IOException

1.3.5 使用演示
import java.io.File;      import java.io.FileNotFoundException;      import java.io.FileOutputStream;      import java.io.IOException;        /*       * 文件操作輸出位元組流       * 		1. 確定文件       * 		2. 創建FileOutputStream       * 		3. 寫入數據到文件中       * 		4. 關閉資源       */      public class Demo2 {      	public static void main(String[] args) {      		writeTest2();      	}        	public static void writeTest2() {      		// 1. 確定文件      		File file = new File("C:/aaa/中國加油.txt");        		// 2. 文件操作位元組輸出流對象      		FileOutputStream fileOutputStream = null;        		try {      			// 3. 創建FileOutputStream      			fileOutputStream = new FileOutputStream(file);        			// 4. 準備byte類型數組      			byte[] bytes = "武漢加油!中國加油!".getBytes();      			byte[] arr = {65, 66, 67, 68, 69, 70, 71};        			fileOutputStream.write(bytes);      			fileOutputStream.write(arr, 2, 3);      		} catch (IOException e) {      			// TODO Auto-generated catch block      			e.printStackTrace();      		} finally {      			// 關閉資源      			if (fileOutputStream != null) {      				try {      					fileOutputStream.close();      				} catch (IOException e) {      					// TODO Auto-generated catch block      					e.printStackTrace();      				}      			}      		}      	}        	public static void wrietTest1() {      		// 1. 確定文件      		File file = new File("C:/aaa/武漢加油.txt");        		// 2. 文件操作位元組輸出流對象      		FileOutputStream fileOutputStream = null;      		try {      			// 3. 創建FileOutputStream      			fileOutputStream = new FileOutputStream(file, true);        			// 4. 寫入數據      			fileOutputStream.write('D');      			fileOutputStream.write('D');      			fileOutputStream.write('D');      			fileOutputStream.write('D');      			fileOutputStream.write('D');      			fileOutputStream.write('D');      		} catch (IOException e) {      			// TODO Auto-generated catch block      			e.printStackTrace();      		} finally {      			// 關閉資源      			if (fileOutputStream != null) {      				try {      					fileOutputStream.close();      				} catch (IOException e) {      					// TODO Auto-generated catch block      					e.printStackTrace();      				}      			}      		}      	}      }

1.4 文件操作字元流

1.4.1 字元流特徵

字元流 = 位元組流 + 解碼過程 位元組組合操作 ==> 對應當前環境編碼集的一個字元 如果字元找不到,該數據無效,需要被刪除。

如果是字元內容操作,效率還可以!!! 如果是非字元操作,凶多吉少!!!

字元流操作文件 個人建議,該文件可以使用notepad 記事本打開無亂碼,可以使用字元流操作。 影片文件,圖片文件,特定格式的文件,都無法使用字元操作。

1.4.2 文件操作輸入字元流

FileReader 文件操作輸入字元流

Constructor 構造方法 FileReader(File file) 根據File類對象創建對應的FileReader字元流輸入對象

FileReader(String pathName) 根據String類型文件路徑創建對應的FileReader字元流輸入對象 如果文件不存在,拋出異常FileNotFoundException

Method 成員方法 int read(); 讀取文件中的一個字元數據,通過返回值返回,返回值類型是int類型,但是在int類型中有且只有低16位數據有效

int read(char[] arr); 讀取文件中的數據保存到字元數組中,返回值類型是讀取到的字元個數

int read(char[] arr, int off, int len); 讀取文件中的數據保存到字元數組中,要求從數組中下標offset開始,到len結束,返回值類型是讀取到的字元個數

以上方法,如果讀取到文件默認,返回值為-1 EOF End Of File 如果讀取操作工作中,出現問題,拋出異常IOException

2.4.3 使用演示

  import java.io.File;      import java.io.FileNotFoundException;      import java.io.FileReader;      import java.io.IOException;        public class Demo4 {      	public static void main(String[] args) {      		long start = System.currentTimeMillis();        		readTest2();        		long end = System.currentTimeMillis();      		System.out.println("Time : " + (end - start));      	}        	// 10      	public static void readTest2() {      		FileReader fileReader = null;      		try {      			fileReader = new FileReader(new File("C:/aaa/3.txt"));        			char[] buf = new char[1024 * 4];      			int length = -1;        			while ((length = fileReader.read(buf)) != -1) {      				System.out.println(new String(buf, 0, length));      			}      		} catch (IOException e) {      			// TODO Auto-generated catch block      			e.printStackTrace();      		} finally {      			if (fileReader != null) {      				try {      					fileReader.close();      				} catch (IOException e) {      					// TODO Auto-generated catch block      					e.printStackTrace();      				}      			}      		}      	}        	// 300      	public static void readTest1() {      		FileReader fileReader = null;      		try {      			fileReader = new FileReader(new File("C:/aaa/3.txt"));        			int content = -1;        			while ((content = fileReader.read()) != -1) {      				System.out.println((char) content);      			}      		} catch (IOException e) {      			// TODO Auto-generated catch block      			e.printStackTrace();      		} finally {      			if (fileReader != null) {      				try {      					fileReader.close();      				} catch (IOException e) {      					// TODO Auto-generated catch block      					e.printStackTrace();      				}      			}      		}      	}      }