1. 程式人生 > >[Java基礎] 位元組流與字元流

[Java基礎] 位元組流與字元流

流的定義

流是個抽象的概念,是對輸入輸出裝置的抽象,Java程式中,對於資料的輸入/輸出操作都是以“流”的方式進行。裝置可以是檔案,網路,記憶體等。

流具有方向性,至於是輸入流還是輸出流則是一個相對的概念,一般以程式為參考,如果資料的流向是程式至裝置,我們成為輸出流,反之我們稱為輸入流。

可以將流想象成一個“水流管道”,水流就在這管道中形成了,自然就出現了方向的概念。

當程式需要從某個資料來源讀入資料的時候,就會開啟一個輸入流,資料來源可以是檔案、記憶體或網路等等。相反地,需要寫出資料到某個資料來源目的地的時候,也會開啟一個輸出流,這個資料來源目的地也可以是檔案、記憶體或網路等等。

流的分類

可以從不同的角度對流進行分類:

1.處理的資料單位不同,可分為:字元流,位元組流

2.資料流方向不同,可分為:輸入流,輸出流

3.功能不同,可分為:節點流,處理流

1. 和 2. 都比較好理解,對於根據功能分類的,可以這麼理解:

節點流:節點流從一個特定的資料來源讀寫資料。即節點流是直接操作檔案,網路等的流,例如FileInputStream和FileOutputStream,他們直接從檔案中讀取或往檔案中寫入位元組流。

處理流:“連線”在已存在的流(節點流或處理流)之上通過對資料的處理為程式提供更為強大的讀寫功能。過濾流是使用一個已經存在的輸入流或輸出流連線建立的,過濾流就是對節點流進行一系列的包裝。例如BufferedInputStream和BufferedOutputStream,使用已經存在的節點流來構造,提供帶緩衝的讀寫,提高了讀寫的效率,以及DataInputStream和DataOutputStream,使用已經存在的節點流來構造,提供了讀寫Java中的基本資料型別的功能。他們都屬於過濾流。

流的結構

Java所有的流類位於java.io包中,都分別繼承字以下四種抽象流型別。

位元組流 字元流
輸入流 InputStream Reader
輸出流 OutputStream Writer

1.繼承自InputStream/OutputStream的流都是用於向程式中輸入/輸出資料,且資料的單位都是位元組(byte=8bit),如圖,深色的為節點流,淺色的為處理流。

 

2.繼承自Reader/Writer的流都是用於向程式中輸入/輸出資料,且資料的單位都是字元(2byte=16bit),如圖,深色的為節點流,淺色的為處理流。

常見的流:

節點流型別常見的有:

對檔案操作的字元流有FileReader/FileWriter,位元組流有FileInputStream/FileOutputStream。

處理流型別常見的有:

緩衝流:緩衝流要“套接”在相應的節點流之上,對讀寫的資料提供了緩衝的功能,提高了讀寫效率,同事增加了一些新的方法。

  位元組緩衝流有BufferedInputStream/BufferedOutputStream,字元緩衝流有BufferedReader/BufferedWriter,字元緩衝流分別提供了讀取和寫入一行的方法ReadLine和NewLine方法。

  對於輸出地緩衝流,寫出的資料,會先寫入到記憶體中,再使用flush方法將記憶體中的資料刷到硬碟。所以,在使用字元緩衝流的時候,一定要先flush,然後再close,避免資料丟失。

轉換流:用於位元組資料到字元資料之間的轉換。

  僅有字元流InputStreamReader/OutputStreamWriter。其中,InputStreamReader需要與InputStream“套接”,OutputStreamWriter需要與OutputStream“套接”。

資料流:提供了讀寫Java中的基本資料型別的功能。

  DataInputStream和DataOutputStream分別繼承自InputStream和OutputStream,需要“套接”在InputStream和OutputStream型別的節點流之上。

物件流:用於直接將物件寫入寫出。

  流類有ObjectInputStream和ObjectOutputStream,本身這兩個方法沒什麼,但是其要寫出的物件有要求,該物件必須實現Serializable介面,來宣告其是可以序列化的。否則,不能用物件流讀寫。

  還有一個關鍵字比較重要,transient,由於修飾實現了Serializable介面的類內的屬性,被該修飾符修飾的屬性,在以物件流的方式輸出的時候,該欄位會被忽略。


package stream;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class IOTest {
    public static void main(String[] args) throws Exception {
		String str = "中國人";
		
//		FileOutputStream fos = new FileOutputStream("1.txt");
//		fos.write(str.getBytes("UTF-8"));
//		fos.close();
		
//		FileWriter fw = new FileWriter("1.txt");
//		fw.write(str);
//		fw.close();
		
		PrintWriter pw = new PrintWriter("1.txt","utf-8");
		pw.write(str);
		pw.close();
		
//		FileReader fr =new FileReader("1.txt");
//		char[] buf = new char[1024];
//		int len =fr.read(buf);
//		String myStr = new String(buf,0,len);
//		System.out.println(myStr);
		
//		FileInputStream fr = new FileInputStream("1.txt");
//		byte[] buf = new byte[1024];
//		int len =fr.read(buf);
//		String myStr = new String(buf,0,len,"UTF-8");
//		System.out.println(myStr);
		
		BufferedReader br =new BufferedReader(
				new InputStreamReader(
						new FileInputStream("1.txt"),"UTF-8"));
				String myStr = br.readLine();
				br.close();
				System.out.println(myStr);
	}
}