1.位元組流
位元組流:InputStream OutputStream
位元組流不需要重新整理流對象的,特有方法:byte[] buf = new byte[fis.available()];//定義一個剛剛好的緩沖區。不用在循環了。
2.位元組流練習:
(1)複制一個圖檔
思路:
1,用位元組讀取流對象和圖檔關聯。
2,用位元組寫入流對象建立一個圖檔檔案。用于存儲擷取到的圖檔資料。
3,通過循環讀寫,完成資料的存儲。
4,關閉資源。
代碼圖例:
(2)複制Mp3
自定義一個位元組流緩沖區,模拟read和close方法。
代碼圖例:
結論:
位元組流的讀一個位元組的read方法為什麼傳回值類型不是byte,而是int。因為有可能會讀到連續8個二進制1的情況,8個二進制1對應的十進制是-1.那麼就會資料還沒有讀完,就結束的情況。因為我們判斷讀取結束是通過結尾标記-1來确定的。是以,為了避免這種情況将讀到的位元組進行int類型的提升。并在保留原位元組資料的情況前面了補了24個0,變成了int類型的數值。而在寫入資料時,隻寫該int類型資料的最低8位。
3.轉換流
InputStreamReader和OutputStreamWriter:FileReader和FileWriter是轉換流的子類,它們有預設的字元編碼集。
轉換流可以指定編碼表。
4.流操作規律:
1,
源:鍵盤錄入。
目的:控制台。
2,需求:想把鍵盤錄入的資料存儲到一個檔案中。
源:鍵盤。
目的:檔案。
3,需求:想要将一個檔案的資料列印在控制台上。
源:檔案。
目的:控制台。
流操作的基本規律:
最痛苦的就是流對象有很多,不知道該用哪一個。
通過三個明确來完成。
1,明确源和目的。
源:輸入流。InputStream Reader
目的:輸出流。OutputStream Writer。
2,操作的資料是否是純文字。
是:字元流。
不是:位元組流。
例如:
需求:将鍵盤錄入的資料儲存到一個檔案中。這個需求中有源和目的都存在。那麼分别分析。源:InputStream Reader是不是純文字?是!Reader。裝置:鍵盤。對應的對象是System.in.
不是選擇Reader嗎?System.in對應的不是位元組流嗎?
為了操作鍵盤的文本資料友善。轉成字元流按照字元串操作是最友善的。是以既然明确了Reader,那麼就将System.in轉換成Reader。用了Reader體系中轉換流,InputStreamReader。:InputStreamReader isr = new InputStreamReader(System.in);
需要提高效率嗎?需要!BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer是否是存文本?是!Writer。
裝置:硬碟。一個檔案。使用 FileWriter。
FileWriter fw = new FileWriter("c.txt");
需要提高效率嗎?需要。BufferedWriter bufw = new BufferedWriter(fw);
**************
擴充一下,想要把錄入的資料按照指定的編碼表(utf-8),将資料存到檔案中。
目的:OutputStream Writer。是否是存文本?是!Writer。
裝置:硬碟。一個檔案。使用 FileWriter。但是FileWriter是使用的預設編碼表。GBK.
但是存儲時,需要加入指定編碼表utf-8。而指定的編碼表隻有轉換流可以指定。是以要使用的對象是OutputStreamWriter。而該轉換流對象要接收一個位元組輸出流。而且還可以操作的檔案的位元組輸出流。FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
需要高效嗎?需要。
BufferedWriter bufw = new BufferedWriter(osw);
是以,記住。轉換流什麼使用。字元和位元組之間的橋梁,通常,涉及到字元編碼轉換時,
需要用到轉換流。
3,當體系明确後,在明确要使用哪個具體的對象。
通過裝置來進行區分:
源裝置:記憶體,硬碟。鍵盤
目的裝置:記憶體,硬碟,控制台。
4.System和Properties
練習:列印日志異常資訊到硬碟
參考代碼:day19\ExceptionInfo.java
練習:列印系統資訊到硬碟
圖例代碼: