IO流概念總結2018-11-14
IO流 (1)簡介: 流的定義:流是指一連串流動的字元,是以先進先出方式傳送資訊的通道。 按流向分:輸出流:OutputStream和Writer為基類 輸入流:InputStream和Reader為基類 按處理資料單元劃分: 位元組流:位元組輸入流:InputStream基類 位元組輸出流:OutputStream基類 字元流:字元輸入流:Reader基類 位元組輸出流:Writer基類
字元流和位元組流的區別: 字元流:顧名思義,該流只能處理字元,但處理字元速度很快 位元組流:可以處理所有以bit為單位儲存的檔案,也就是說可以處理所有的檔案,但是在處理字元上的速度不如字元流 字元流和位元組流
字元流的由來: 因為資料編碼的不同,而有了對字元進行高效操作的流物件。本質其實就是基於位元組流讀取時,去查了指定的碼錶。 位元組流和字元流的區別:
讀寫單位不同:位元組流以位元組(8bit)為單位,字元流以字元為單位,根據碼錶對映字元,一次可能讀多個位元組。 處理物件不同:位元組流能處理所有型別的資料(如圖片、avi等),而字元流只能處理字元型別的資料。 結論:只要是處理純文字資料,就優先考慮使用字元流。 除此之外都使用位元組流。
字元流: 字元流 = 位元組流 + 編碼表 編碼: 就是把字串轉換成位元組陣列
-
把一個字串轉換成一個位元組陣列
-
public byte[] getBytes();使用平臺的預設字符集將此 String編碼為 byte 序列,並將結果儲存到一個新的 byte 陣列中。
-
public byte[] getBytes(String charsetName) 使用指定的字符集將此 String 編碼為 byte 序列,並將結果儲存到一個新的 byte 陣列中。
- 解碼: 把位元組陣列轉換成字串
-
public String(byte[] bytes): 通過使用平臺的預設字符集解碼指定的 byte 陣列,構造一個新的 String。
-
public String(byte[] bytes, String charsetName) 通過使用指定的 charset 解碼指定的 byte 陣列,構造一個新的 String。
- 使用什麼字符集進行編碼,那麼就是使用什麼字符集進行解碼
- 老地方 ----- 十進位制 ---- 二進位制 ---- 發出去
- 接收 ---- 二進位制 ---- 十進位制 — 老地方 編碼表:把計算機底層的二進位制資料轉換成我們能看到的字元
- ASCII
- GB2312 — GBK
- Unicode 所有的字元都佔2個位元組
- UTF-8 長度可變的碼錶
- ANSI:本地編碼表 gbk
- Java中的字串預設使用的ANSI(gbk 輸入流和輸出流
對輸入流只能進行讀操作,對輸出流只能進行寫操作,程式中需要根據待傳輸資料的不同特性而使用不同的流。
Io體系的基類(InputStream/Reader,OutputStream/Writer)。
位元組流和字元流的操作方式基本一致,只是操作的資料單元不同——位元組流的操作單元是位元組,字元流的操作單元是字元。所以位元組流和字元流就整理在一起了。 InputStream和Reader是所有輸入流的抽象基類,本身並不能建立例項來執行輸入,但它們將成為所有輸入流的模板,所以它們的方法是所有輸入流都可使用的方法。 在InputStream裡面包含如下3個方法。
int read(); 從輸入流中讀取單個位元組(相當於從圖15.5所示的水管中取出一滴水),返回所讀取的位元組資料(位元組資料可直接轉換為int型別)。 int read(byte[] b)從輸入流中最多讀取b.length個位元組的資料,並將其儲存在位元組陣列b中,返回實際讀取的位元組數。 int read(byte[] b,int off,int len); 從輸入流中最多讀取len個位元組的資料,並將其儲存在陣列b中,放入陣列b中時,並不是從陣列起點開始,而是從off位置開始,返回實際讀取的位元組數。 在Reader中包含如下3個方法。
int read(); 從輸入流中讀取單個字元(相當於從圖15.5所示的水管中取出一滴水),返回所讀取的字元資料(位元組資料可直接轉換為int型別)。 int read(char[] b)從輸入流中最多讀取b.length個字元的資料,並將其儲存在位元組陣列b中,返回實際讀取的字元數。 int read(char[] b,int off,int len); 從輸入流中最多讀取len個字元的資料,並將其儲存在陣列b中,放入陣列b中時,並不是從陣列起點開始,而是從off位置開始,返回實際讀取的字元數。
InputStream和Reader提供的一些移動指標的方法:
void mark(int readAheadLimit); 在記錄指標當前位置記錄一個標記(mark)。 boolean markSupported(); 判斷此輸入流是否支援mark()操作,即是否支援記錄標記。 void reset(); 將此流的記錄指標重新定位到上一次記錄標記(mark)的位置。 long skip(long n); 記錄指標向前移動n個位元組/字元。
通用規則:使用java的io流執行輸出時,不要忘記關閉輸出流,關閉輸出流除了可以保證流的物理資源被回收之外,可能還可以將輸出流緩衝區中的資料flush到物理節點中裡(因為在執行close()方法之前,自動執行輸出流的flush()方法)。java很多輸出流預設都提供了快取功能,其實我們沒有必要刻意去記憶哪些流有快取功能,哪些流沒有,只有正常關閉所有的輸出流即可保證程式正常
轉換流的使用(InputStreamReader/OutputStreamWriter): java使用System.in代表輸入。而且鍵盤輸入內容都是文字內容,所以可以使用InputStreamReader將其包裝成BufferedReader,利用BufferedReader的readLine()方法可以一次讀取一行內容
物件流的使用(ObjectInputStream/ObjectOutputStream)的使用: 使用物件流的一些注意事項 1.讀取順序和寫入順序一定要一致,不然會讀取出錯。 2.在物件屬性前面加transient關鍵字,則該物件的屬性不會被序列化。