1. 程式人生 > >20180119:緩衝流、轉換流、標準輸入輸出流

20180119:緩衝流、轉換流、標準輸入輸出流

今天重點學習瞭解了緩衝流和轉換流的內容,標準輸入輸出流並不複雜,較為容易理解

一、緩衝流

緩衝流是處理流的一種,建立在相應的節點流之上,對讀寫的資料提供了緩衝的功能,作用就是為了提高讀寫的效率,由於普通的輸入流在讀取檔案時效率較低,建立自定義的緩衝區也造成了記憶體的浪費;同時,程式通過輸出流向檔案中寫入內容時也有一定的侷限性,緩衝流其實就是對他們進行再次包裝(體現了裝飾者設計模式),從而大大提高了讀寫的效率,增加了新的非常有用的方法。

JDK提供了四種緩衝流:

 BufferedInputStream:可以對任何InputStream流進行包裝;

  BufferedOutputStream:可以對任何的OutputStream流進行包裝

BufferedReader:可以對任何的Reader流進行包裝(新增了readLine()方法用於讀取一行字串

BufferedWriter:可以對任何的Writer流進行包裝(新增了newLine()方法用於寫出一個行分隔符

 對於緩衝輸出流,寫出的資料會先快取在記憶體緩衝區中,關閉此流前要用flush()方法將快取區的資料寫出。關閉緩衝流時,

會自動關閉緩衝流所包裝的所有底層流。

1.1 BufferedInputStream(位元組緩衝流)

package buffer;

import java.io.*;

public class BufferedInputStreamDemo {
	
	public static void main(String[] args) {
		
		File file = new File("e:"+File.separator+"test.txt");
		
		InputStream is = null;
		BufferedInputStream bis = null;
		
		try {
			is = new FileInputStream(file);
			bis = new BufferedInputStream(is);
			int data = 0;
			while((data=bis.read()) != -1){
				System.out.print((char)data);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

1.2 BufferedOutputStream(緩衝位元組輸出流)
package buffer;

import java.io.*;

public class BufferedOutputStreamDemo {
	
	public static void main(String[] args) {
		
		File file = new File("e:"+File.separator+"test.txt");
		
		OutputStream os = null;
		BufferedOutputStream bos = null;
		
		try {
			os = new FileOutputStream(file);
			bos = new BufferedOutputStream(os);
			
			bos.write("做人不可好勇鬥狠,謙虛謹慎四平八穩!".getBytes());
			bos.flush(); //需要重新整理緩衝區才能將內容寫入到檔案中
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
}
1.3 BufferedReader(緩衝字元輸入流)
package buffer;

import java.io.*;

public class BufferedReaderDemo {
	
	public static void main(String[] args) {
		
		File file = new File("E:"+File.separator+"test.txt");
		
		Reader r = null;
		BufferedReader br = null;
		
		try {
			r = new FileReader(file);
			br = new BufferedReader(r);
			int row=0;
			//讀取每一行的資料並加上行號
			String str = "";
			while((str=br.readLine()) != null){
				row++;
				System.out.println(row + ".\t" + str);
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				br.close();
				r.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
		
	}
	
}
1.4 BufferedWriter(緩衝字元輸出流)
package buffer;

import java.io.*;

public class BufferedWriterDemo {
	
	public static void main(String[] args) {
		
		File file = new File("d:"+File.separator+"test.txt");
		
		Writer w = null;
		BufferedWriter bw = null;
		
		try {
			
			w = new FileWriter(file);
			bw = new BufferedWriter(w);
			
			//對檔案內容進行操作了
			bw.write("我是你爹");
			bw.newLine();
			bw.write("我是你爸爸");
			bw.newLine();
			bw.write("開心不?");
			bw.newLine();
			//上面僅僅是將內容寫入緩衝區,還要重新整理緩衝區將內容真正寫入檔案中
			bw.flush();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
}

二、轉換流

IO包中實際上只有位元組流,字元流是在位元組流的基礎上轉換出來的,轉換流用於位元組流和字元流的轉換。

JDK提供了兩種轉換流:

1. InputStreamReader: 是Reader的子類,將輸入的位元組流變為字元流,即:將一個位元組流的輸入物件變為字元流的輸入物件。

InputStreamReader需要和InputStream”套接”,它可以將位元組流中讀入的位元組解碼成字元。即:InputStreanReader雖然是Reader的子類,但是它包裝的是InputStream流物件。

2. OutputStreamWriter:Writer的子類,將輸出的字元流轉變為位元組流,即:將一個字元的輸出物件變為位元組流的輸出物件。

OutStreamWriter需要和OutputStream”套接”,它可以將要寫入位元組流的字元編碼成位元組。

三、轉換步驟

1.寫出程式: 程式—>字元資料(記憶體中的資料)-->轉換流(OutputStreamReader,將輸出的字元流變為位元組流)-->位元組流-->檔案

2.讀入程式:檔案-->位元組流—>InputStreamWriter(將輸入的位元組流轉變為字元流)-->字元資料-->程式

 注:InputStreamReader可以代替Scanner類在控制檯接收鍵盤輸入。
四、Properties

Properties是HashTable的一個子類,主要用於讀取java配置檔案的資訊,各種語言都有自己的配置的檔案,這樣做主要是為了方便使用者,使得程式設計師能夠脫離程式修改相應的變數值。

在java中的配置檔案是.propertie的檔案,格式為文字檔案,檔案的內容通常是"鍵 = 值"的形式,文字註釋資訊通常用"#"來進行註釋。

 Properties的類繼承如下:


它提供了幾個主要的方法:

1.getProperty(String key):用指定的鍵在此屬性列表中搜索屬性。也就是通過引數 key ,得到 key 所對應的 value。

2.load(InputStream is): 從輸入流中讀取屬性列表(鍵值對),通過對指定的檔案進行裝載來獲取該檔案中所有的鍵值對,以供getProperty(String key)來搜尋

3.setProperty(String key,String value):呼叫HashTable的方法put,呼叫此方法來設定鍵值對

4.store(OutputStream os,String comments):以適合使用load方法載入到Properties表中的格式,將此Properties表中的屬性列表(鍵和元素對)寫入到指定的檔案中去

5.clear(): 清除所有的鍵值對,該方法在基類中提供。

舉一個儲存屬性檔案並讀取的例子:

屬性檔案的建立並存儲在磁碟上:

package properties;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

public class PropertiesStore {
	
	//利用Properties屬性集合建立屬性檔案,屬性檔案可以是.properties或者是.xml檔案
	public static void main(String[] args) {
		
		Properties pro = new Properties();
		//設定屬性值
		pro.setProperty("name","Tom");
		pro.setProperty("sex", "male");
		pro.setProperty("age","three");
		//寫入到磁碟檔案中
		OutputStream os = null;
		try {
			os = new FileOutputStream("E:"+File.separator+"dnf.properties");
			//向檔案中寫入內容並添加註釋
			pro.store(os, "this is a boys");
			System.out.println("建立屬性檔案成功了!");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
}

 讀取 的屬性檔案如下:

讀取該磁碟檔案,並通過key值得到value值:

package properties;

import java.io.*;
import java.util.Properties;

public class PropertiesLoad {
	
	public static void main(String[] args) {
		Properties pro = new Properties();
		
		InputStream is = null;
		try {
			is = new FileInputStream("E:"+File.separator+"dnf.properties");
			pro.load(is);
			System.out.println(pro.getProperty("name"));
			System.out.println(pro.getProperty("age"));
			System.out.println(pro.getProperty("sex"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}