Java IO詳解(五)------包裝流


File 類的介紹:http://www.cnblogs.com/ysocean/p/6851878.html

Java IO 流的分類介紹:http://www.cnblogs.com/ysocean/p/6854098.html

Java IO 字節輸入輸出流:http://www.cnblogs.com/ysocean/p/6854541.html

Java IO 字符輸入輸出流:https://i.cnblogs.com/EditPosts.aspx?postid=6859242

 

  我們在 Java IO 流的分類介紹  這篇博客中介紹知道:

  根據功能分為節點流和包裝流(處理流)

    節點流:可以從或向一個特定的地方(節點)讀寫數據。如FileReader.

    處理流:是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫。如BufferedReader.處理流的構造方法總是要帶一個其他的流對象做參數。一個流對象經過其他流的多次包裝,稱為流的鏈接。

 

1、前面講的字符輸入輸出流,字節輸入輸出流都是字節流。那么什么是包裝流呢?

  ①、包裝流隱藏了底層節點流的差異,並對外提供了更方便的輸入\輸出功能,讓我們只關心這個高級流的操作

  ②、使用包裝流包裝了節點流,程序直接操作包裝流,而底層還是節點流和IO設備操作

  ③、關閉包裝流的時候,只需要關閉包裝流即可

 

 

 

2、緩沖流

  

  緩沖流:是一個包裝流,目的是緩存作用,加快讀取和寫入數據的速度。

  字節緩沖流:BufferedInputStream、BufferedOutputStream

  字符緩沖流:BufferedReader、BufferedWriter

案情回放:我們在將字符輸入輸出流、字節輸入輸出流的時候,讀取操作,通常都會定義一個字節或字符數組,將讀取/寫入的數據先存放到這個數組里面,然后在取數組里面的數據。這比我們一個一個的讀取/寫入數據要快很多,而這也就是緩沖流的由來。只不過緩沖流里面定義了一個 數組用來存儲我們讀取/寫入的數據,當內部定義的數組滿了(注意:我們操作的時候外部還是會定義一個小的數組,小數組放入到內部數組中),就會進行下一步操作。 

      

下面是沒有用緩沖流的操作:   

//1、創建目標對象,輸入流表示那個文件的數據保存到程序中。不寫盤符,默認該文件是在該項目的根目錄下
			//a.txt 保存的文件內容為:AAaBCDEF
		File target = new File("io"+File.separator+"a.txt");
		//2、創建輸入流對象
		InputStream in = new FileInputStream(target);
		//3、具體的 IO 操作(讀取 a.txt 文件中的數據到程序中)
			/**
			 * 注意:讀取文件中的數據,讀到最后沒有數據時,返回-1
			 * 	int read():讀取一個字節,返回讀取的字節
			 * 	int read(byte[] b):讀取多個字節,並保存到數組 b 中,從數組 b 的索引為 0 的位置開始存儲,返回讀取了幾個字節
			 * 	int read(byte[] b,int off,int len):讀取多個字節,並存儲到數組 b 中,從數組b 的索引為 0 的位置開始,長度為len個字節
			 */
		//int read():讀取一個字節,返回讀取的字節
		int data1 = in.read();//獲取 a.txt 文件中的數據的第一個字節
		System.out.println((char)data1); //A
		//int read(byte[] b):讀取多個字節保存到數組b 中
		byte[] buffer  = new byte[10];//這里我們定義了一個 長度為 10 的字節數組,用來存儲讀取的數據
		in.read(buffer);//獲取 a.txt 文件中的前10 個字節,並存儲到 buffer 數組中
		System.out.println(Arrays.toString(buffer)); //[65, 97, 66, 67, 68, 69, 70, 0, 0, 0]
		System.out.println(new String(buffer)); //AaBCDEF[][][]
		
		//int read(byte[] b,int off,int len):讀取多個字節,並存儲到數組 b 中,從索引 off 開始到 len
		in.read(buffer, 0, 3);
		System.out.println(Arrays.toString(buffer)); //[65, 97, 66, 0, 0, 0, 0, 0, 0, 0]
		System.out.println(new String(buffer)); //AaB[][][][][][][]
		//4、關閉流資源
		in.close();

  我們查看 緩沖流的 JDK 底層源碼,可以看到,程序中定義了這樣的 緩存數組,大小為 8192

  BufferedInputStream:

        

 

 

  BufferedOutputStream:

      

//字節緩沖輸入流
		BufferedInputStream bis = new BufferedInputStream(
				new FileInputStream("io"+File.separator+"a.txt"));
		//定義一個字節數組,用來存儲數據
		byte[] buffer = new byte[1024];
		int len = -1;//定義一個整數,表示讀取的字節數
		while((len=bis.read(buffer))!=-1){
			System.out.println(new String(buffer,0,len));
		}
		//關閉流資源
		bis.close();

//字節緩沖輸出流 BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("io"+File.separator+"a.txt")); bos.write("ABCD".getBytes()); bos.close();

 

//字符緩沖輸入流
		BufferedReader br = new BufferedReader(
				new FileReader("io"+File.separator+"a.txt"));
		char[] buffer = new char[10];
		int len = -1;
		while((len=br.read(buffer))!=-1){
			System.out.println(new String(buffer,0,len));
		}
		br.close();
		
		//字符緩沖輸出流
		BufferedWriter bw = new BufferedWriter(
				new FileWriter("io"+File.separator+"a.txt"));
		bw.write("ABCD");
		bw.close();

  

 

 

 3、轉換流:把字節流轉換為字符流

  InputStreamReader:把字節輸入流轉換為字符輸入流

  OutputStreamWriter:把字節輸出流轉換為字符輸出流

   

 

 用轉換流進行文件的復制:

/**
		 * 將 a.txt 文件 復制到 b.txt 中
		 */
		//1、創建源和目標
		File srcFile = new File("io"+File.separator+"a.txt");
		File descFile = new File("io"+File.separator+"b.txt");
		//2、創建字節輸入輸出流對象
		InputStream in = new FileInputStream(srcFile);
		OutputStream out = new FileOutputStream(descFile);
		//3、創建轉換輸入輸出對象
		Reader rd = new InputStreamReader(in);
		Writer wt = new OutputStreamWriter(out);
		//3、讀取和寫入操作
		char[] buffer = new char[10];//創建一個容量為 10 的字符數組,存儲已經讀取的數據
		int len = -1;//表示已經讀取了多少個字符,如果是 -1,表示已經讀取到文件的末尾
		while((len=rd.read(buffer))!=-1){
			wt.write(buffer, 0, len);
		}
		//4、關閉流資源
		rd.close();
		wt.close();

  

 

 4、內存流(數組流):

  把數據先臨時存在數組中,也就是內存中。所以關閉 內存流是無效的,關閉后還是可以調用這個類的方法。底層源碼的 close()是一個空方法

        

 

  ①、字節內存流:ByteArrayOutputStream 、ByteArrayInputStream

//字節數組輸出流:程序---》內存
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		//將數據寫入到內存中
		bos.write("ABCD".getBytes());
		//創建一個新分配的字節數組。 其大小是此輸出流的當前大小,緩沖區的有效內容已被復制到其中。 
		byte[] temp = bos.toByteArray();
		System.out.println(new String(temp,0,temp.length));
		
		byte[] buffer = new byte[10];
		///字節數組輸入流:內存---》程序
		ByteArrayInputStream bis = new ByteArrayInputStream(temp);
		int len = -1;
		while((len=bis.read(buffer))!=-1){
			System.out.println(new String(buffer,0,len));
		}
		
		//這里不寫也沒事,因為源碼中的 close()是一個空的方法體
		bos.close();
		bis.close();

  

  ②、字符內存流:CharArrayReader、CharArrayWriter

  

//字符數組輸出流
		CharArrayWriter caw = new CharArrayWriter();
		caw.write("ABCD");
		//返回內存數據的副本
		char[] temp = caw.toCharArray();
		System.out.println(new String(temp));
		
		//字符數組輸入流
		CharArrayReader car = new CharArrayReader(temp);
		char[] buffer = new char[10];
		int len = -1;
		while((len=car.read(buffer))!=-1){
			System.out.println(new String(buffer,0,len));
		}

  

  ③、字符串流:StringReader,StringWriter(把數據臨時存儲到字符串中)

 

//字符串輸出流,底層采用 StringBuffer 進行拼接
		StringWriter sw = new StringWriter();
		sw.write("ABCD");
		sw.write("帥鍋");
		System.out.println(sw.toString());//ABCD帥鍋

		//字符串輸入流
		StringReader sr = new StringReader(sw.toString());
		char[] buffer = new char[10];
		int len = -1;
		while((len=sr.read(buffer))!=-1){
			System.out.println(new String(buffer,0,len));//ABCD帥鍋
		}

  

 

 

5、合並流:把多個輸入流合並為一個流,也叫順序流,因為在讀取的時候是先讀第一個,讀完了在讀下面一個流。

 

//定義字節輸入合並流
		SequenceInputStream seinput = new SequenceInputStream(
				new FileInputStream("io/a.txt"), new FileInputStream("io/b.txt"));
		byte[] buffer = new byte[10];
		int len = -1;
		while((len=seinput.read(buffer))!=-1){
			System.out.println(new String(buffer,0,len));
		}
		
		seinput.close();

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM