1. 程式人生 > >Java 位元組流 字元流 轉換流

Java 位元組流 字元流 轉換流

我們知道Java中的流分為字元流和位元組流,其中字元流主要針對字元文字進行處理,而位元組流處理範圍更為廣泛,畢竟圖片、電影等只要是檔案都是以二進位制的形式存在的,而不是字元。
字元流:
FileReader
FileWriter。


BufferedReader
BufferedWriter


位元組流:
FileInputStream
FileOutputStream


BufferedInputStream
BufferedOutputStream

我們看一下J2SE文件:


BufferedReader(Reader in):建立一個使用預設大小輸入緩衝區的緩衝字元輸入流。
可以看出BufferedReader是一個Reader的子類,建構函式傳進來的是父類Reader類,其實是裝飾者模式,將父類比較低效的讀取資料的方式做成了比較高效的緩衝區讀取方式。
 String readLine():讀取一個文字行。
它有一個方法readLine(),直接讀取一行,相對於父類Reader的read()方法更加方便。


System.in:對應的標準輸入裝置:鍵盤。
static InputStreamin :“標準”輸入流。
我們可以寫一個類來使用System中的靜態方法in來從鍵盤讀取資料:

<span style="font-size:18px;">import java.io.*;
class  ReadIn{
	public static void main(String[] args) throws IOException{
		InputStream inin = System.in;		//新建一個InputStream物件,讀取位置為鍵盤
		StringBuilder sb = new StringBuilder();	//用於儲存讀入的字元,相當於自己建了一個快取區

		while(true){
			int ch = inin.read();			//讀取位元組
			if(ch=='\r')
				continue;

			if(ch=='\n'){
				String s = sb.toString();//讀到回車符就轉成String,看看是否是"over",是就退出度數
				if("over".equals(s))
					break;
				else{
					System.out.println(s.toUpperCase());//不是"over"的話就不退出,一行讀取完畢,輸出到螢幕上
					sb.delete(0,sb.length());	//清空快取StringBuilder sb
				}
			}
			else
				sb.append((char)ch);	//如果沒讀到換行符,就繼續往快取StringBuilder裡新增讀取的字元
		}
	}
}</span>

System的in的型別是InputStream,屬於位元組流,和BufferedReader屬於不同的流類。在InputStream中沒有readLine()這樣的整行讀取方法,只有read()。
那麼能不能直接使用readLine()方法來完成鍵盤錄入的一行資料的讀取呢?
即“能不能將位元組流轉成字元流,然後再使用字元流緩衝區的readLine方法呢”?
可以的!
在字元流中有這樣的字元流:
將位元組流轉換成字元流的橋樑——InputStreamReader;
InputStreamReader(InputStream in) :建立一個使用預設字符集的 InputStreamReader。傳入的物件是InputStream型別,而自己本身是Reader的子類。
將字元流轉換成位元組流的橋樑——OutputStreamWriter。
OutputStreamWriter(OutputStream out) :建立使用預設字元編碼的 OutputStreamWriter。傳入的物件是OutputStream型別,而自己本身是Writer的子類。
從名字就可以看出,他們分別屬於(從屬關係看名字的後半部分)字元流Reader和Writer,他們的功能(功能看名字的前半部分)和位元組流InputStream、OutputStream相關。
<span style="font-size:18px;">import java.io.*;
class  TransStreamDemo{
	public static void main(String[] args) throws IOException{
		InputStream in = System.in;				//獲取鍵盤錄入物件。
		InputStreamReader isr = new InputStreamReader(in);	//將位元組流物件轉成字元流物件,使用轉換流。InputStreamReader
		BufferedReader bufr = new BufferedReader(isr);		//為了提高效率,將字串進行緩衝區技術高效操作。使用BufferedReader

//		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));	//最常見寫法,以後都這樣寫!!!

		OutputStream out = System.out;
		OutputStreamWriter osw = new OutputStreamWriter(out);
		BufferedWriter bufw = new BufferedWriter(osw);
//		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));	//同上!!!

		String line = null;

		while( ( line = bufr.readLine() ) != null ){
			if("over".equals(line))
				break;
			bufw.write(line.toUpperCase());	//bufw將osw包裝了,osw將out包裝了,本例中out是Syetem.out的物件實現,所以原本用System.out.println的地方直接可以用包裝後的bufw輸出字串。
			bufw.newLine();			//輸出換行符:可以根據Linux和Windows的不同自動輸出\n或\r\n
			bufw.flush();			//輸出流有緩衝區,需要flush才輸出來
		}

		bufr.close();

	}
}</span>

即——
從檔案讀取字元,用FileReader,但是為了讓其讀取更高效,使用BufferedReader將其包裝一下;
從鍵盤讀取資料,(新建一個InputStream物件獲取鍵盤錄入物件,)用InputStreamReader轉換流將InputStream轉換,然後用BufferedReader將InputStreamReader包裝。
當然InputStream也可以從檔案讀取,這個時候使用的就不是InputStream in = System.in,而是InputStream in = new FileInputStream(String fileName)。
即:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(String fileName)));