java基礎之IO流

1. 流的分類:
根據 輸入流(讀) 和 輸出流(寫)。

同時也可以輸入或輸出的數據不同分爲 字節流 和字符流。

流的體系因功能的不同,但是根據他們的共性,不斷的抽取,形成繼承體系。一共有四個基類,並且都是抽象類:

字節流 : InputStream OutputStream

字符流:  Reader Writer

在這四個體系中,他們的子類有一個共同的特點,前綴是功能名稱,後綴是父類名稱。例如:

字符流: FileReader FileWriter

BufferReader BufferWriter

字節流: FileInputStream FileOutputStream

BufferInputStream BufferOutputStream

IO流:用於處理設備上的數據。 流:可以理解爲數據的流動,就是數據流。IO 流最終要以對象來體現,對象都封裝在 IO 包中。

2. 字節流:處理字節數據的流對象。設備上的數據無論是圖片或者dvd,文字,它們都以二進制存儲的。二進制的最終都是以一個8位爲數據單元進行體現,所以計算機中的最小數據單元就是
字節。意味着,字節流可以處理設備上的所有數據,所以字節流一樣可以處理字符數據。

3. 字符流:因爲字符每個國家都不一樣,所以涉及到了字符編碼問題,那麼GBK編碼的中文用unicode編碼解析是有問題的,所以需要獲取中文字節數據的同時+ 指定的編碼表纔可以解析正確
數據。爲了方便於文字的解析,所以將字節流和編碼表封裝成對象,這個對象就是字符流。只要操作字符數據,優先考慮使用字符流體系。

4. 注意 close() 和 flush() 的區別:
前者將緩衝區的數據刷出,但是流還是可以使用的;後者則是直接將流關閉了,同時緩衝區的數據會被刷出,並且該動作是流操作最後必須執行的。這樣可以避免資源的浪費。

5. IO 異常的處理:一定要寫 finally() 語句。

6. FileWriter寫入數據的細節:
1:window中的換行符:\r\n兩個符號組成。 linux:\n。
2:續寫數據,只要在構造函數中傳入新的參數true。
3:目錄分割符:window \\  /

7. FileReader:使用Reader體系,讀取一個文本文件中的數據。返回 -1 ,標誌讀到結尾。

8. 字符流的緩衝區: 提高對數據的讀寫效率

對應類: BufferedWriter BufferedReader 

緩衝區中提供了一個跨平臺的換行符  newLine();

9. 裝飾設計模式: 當想要對已有的對象進行功能增強時,可以定義類,將已有對象傳入,基於已有的功能,並提供加強功能。那麼自定義的該類稱爲裝飾類

裝飾類通常會通過構造方法接收被裝飾的對象

並基於被裝飾的對象的功能,提供更強的功能

10. 裝飾類比繼承類要靈活,避免了繼承體系的臃腫。 而且降低了類與類之間的關係

裝飾類因爲增強已有對象,具備的功能與已有的的是相同。只不過提供了更加強大的功能。所以裝飾類與被裝飾類通常屬於一個體系中的

11. IO中的使用到了一個設計模式:裝飾設計模式。
裝飾設計模式解決:對一組類進行功能的增強。

包裝:寫一個類(包裝類)對被包裝對象進行包裝;
  1、包裝類和被包裝對象要實現同樣的接口;
2、包裝類要持有一個被包裝對象;
  3、包裝類在實現接口時,大部分方法是靠調用被包裝對象來實現的,對於需要修改的方法我們自己實現;

12. 字符流:
Reader:用於讀取字符流的抽象類。子類必須實現的方法只有 read(char[], int, int) 和 close()。
    
|---BufferedReader:從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。 可以指定緩衝區的大小,或者可使用默認的大小。大多數情況下,默認值就足夠大了。
        
|---LineNumberReader:跟蹤行號的緩衝字符輸入流。此類定義了方法 setLineNumber(int) 和 getLineNumber(),它們可分別用於設置和獲取當前行號。
     
|---InputStreamReader:是字節流通向字符流的橋樑:它使用指定的 charset 讀取字節並將其解碼爲字符。它使用的字符集可以由名稱指定或顯式給定,或者可以接受平臺默認的
字符集。

        |---FileReader:用來讀取字符文件的便捷類。此類的構造方法假定默認字符編碼和默認字節緩衝區大小都是適當的。要自己指定這些值,可以先在 FileInputStream 上構造一個 InputStreamReader。

        |---CharArrayReader:
     
|---StringReader:

13. 字符流:
Writer:寫入字符流的抽象類。子類必須實現的方法僅有 write(char[], int, int)、flush() 和 close()。
     
|---BufferedWriter:將文本寫入字符輸出流,緩衝各個字符,從而提供單個字符、數組和字符串的高效寫入。
    
|---OutputStreamWriter:是字符流通向字節流的橋樑:可使用指定的 charset 將要寫入流中的字符編碼成字節。它使用的字符集可以由名稱指定或顯式給定,否則將接受平臺默
認的字符集。
      
 |---FileWriter:用來寫入字符文件的便捷類。此類的構造方法假定默認字符編碼和默認字節緩衝區大小都是可接受的。要自己指定這些值,可以先在 FileOutputStream 上構造一個 OutputStreamWriter。
    
|---PrintWriter:
     
|---CharArrayWriter:
    
|---StringWriter:

14. 字節流:
InputStream:是表示字節輸入流的所有類的超類。
    
|--- FileInputStream:從文件系統中的某個文件中獲得輸入字節。哪些文件可用取決於主機環境。FileInputStream 用於讀取諸如圖像數據之類的原始字節流。要讀取字符流,請
考慮使用 FileReader。

        |--- FilterInputStream:包含其他一些輸入流,它將這些流用作其基本數據源,它可以直接傳輸數據或提供一些額外的功能。
   
        |--- BufferedInputStream:該類實現緩衝的輸入流。
        
|--- Stream:
        
  |--- ObjectInputStream:

        |--- PipedInputStream:

15. 字節流:
OutputStream:此抽象類是表示輸出字節流的所有類的超類。
 
     |--- FileOutputStream:文件輸出流是用於將數據寫入 File 或 FileDescriptor 的輸出流。
 
     |--- FilterOutputStream:此類是過濾輸出流的所有類的超類。
 
       |--- BufferedOutputStream:該類實現緩衝的輸出流。
        
       |--- PrintStream:
       
       |--- DataOutputStream:
     
     |--- ObjectOutputStream:

     |--- PipedOutputStream:

16. 緩衝區是提高效率用的,給誰提高呢?
BufferedWriter:是給字符輸出流提高效率用的,那就意味着,緩衝區對象建立時,必須要先有流對象。明確要提高具體的流對象的效率。

17. 流對象:其實很簡單,就是讀取和寫入。但是因爲功能的不同,流的體系中提供N多的對象。那麼開始時,到底該用哪個對象更爲合適呢?這就需要明確流的操作規律。

18. 流的操作規律:
1,明確源和目的。
數據源:就是需要讀取,可以使用兩個體系:InputStream、Reader;
數據匯:就是需要寫入,可以使用兩個體系:OutputStream、Writer;

2,操作的數據是否是純文本數據?
如果是:數據源:Reader
   數據匯:Writer 
如果不是:數據源:InputStream
    數據匯:OutputStream

3,雖然確定了一個體系,但是該體系中有太多的對象,到底用哪個呢?
明確操作的數據設備。
數據源對應的設備:硬盤(File),內存(數組),鍵盤(System.in)
數據匯對應的設備:硬盤(File),內存(數組),控制檯(System.out)。

4,需要在基本操作上附加其他功能嗎?比如緩衝。
如果需要就進行裝飾。

19. 轉換流特有功能:轉換流可以將字節轉成字符,原因在於,將獲取到的字節通過查編碼表獲取到指定對應字符。
轉換流的最強功能就是基於 字節流 + 編碼表 。沒有轉換,沒有字符流。

20. 發現轉換流有一個子類就是操作文件的字符流對象:
InputStreamReader
|--FileReader
OutputStreamWriter
|--FileWrier

想要操作文本文件,必須要進行編碼轉換,而編碼轉換動作轉換流都完成了。所以操作文件的流對象只要繼承自轉換流就可以讀取一個字符了。

21. 如果需要制定碼錶,必須用轉換流。
轉換流 = 字節流+編碼表。

轉換流的子類File = 字節流 + 默認編碼表。

凡是操作設備上的文本數據,涉及編碼轉換,必須使用轉換流。

22. File 類:用來將文件或者文件夾封裝成對象,方便對文件和文件夾的屬性信息進行操作。File 類可以作爲參數傳遞給流的構造函數

23. File 類常見方法:
1:創建。
boolean createNewFile():在指定目錄下創建文件,如果該文件已存在,則不創建。而對操作文件的輸出流而言,輸出流對象已建立,就會創建文件,如果文件已存在,會
覆蓋。除非續寫。

boolean mkdir():創建此抽象路徑名指定的目錄。

boolean mkdirs():創建多級目錄。 

2:刪除。
boolean delete():刪除此抽象路徑名錶示的文件或目錄。

void deleteOnExit():在虛擬機退出時刪除。

注意:在刪除文件夾時,必須保證這個文件夾中沒有任何內容,纔可以將該文件夾用delete刪除。window的刪除動作,是從裏往外刪。注意:java刪除文件不走回收站。要慎用。

3:獲取.
long length():獲取文件大小。

String getName():返回由此抽象路徑名錶示的文件或目錄的名稱。

String getPath():將此抽象路徑名轉換爲一個路徑名字符串。

String getAbsolutePath():返回此抽象路徑名的絕對路徑名字符串。

String getParent():返回此抽象路徑名父目錄的抽象路徑名,如果此路徑名沒有指定父目錄,則返回 null。

long lastModified():返回此抽象路徑名錶示的文件最後一次被修改的時間。

File.pathSeparator:返回當前系統默認的路徑分隔符,windows默認爲 “;”。

File.Separator:返回當前系統默認的目錄分隔符,windows默認爲 “\”。

4:判斷:
boolean exists():判斷文件或者文件夾是否存在。

boolean isDirectory():測試此抽象路徑名錶示的文件是否是一個目錄。

boolean isFile():測試此抽象路徑名錶示的文件是否是一個標準文件。

boolean isHidden():測試此抽象路徑名指定的文件是否是一個隱藏文件。

boolean isAbsolute():測試此抽象路徑名是否爲絕對路徑名。

5:重命名。
boolean renameTo(File dest):可以實現移動的效果。剪切+重命名。

構造函數可以接受的參數類型:
1.file 對象。File
2. 字符串路徑。 String
3. 字節輸出流。 OutputStream
4. 字符輸出流。 Writer

24. Java.io.outputstream.PrintStream:打印流
1:提供了更多的功能,比如打印方法。可以直接打印任意類型的數據。

2:它有一個自動刷新機制,創建該對象,指定參數,對於指定方法可以自動刷新。

3:它使用的本機默認的字符編碼. 

4:該流的print方法不拋出IOException。

25. PrintWriter:具備了PrintStream的特點同時,還有自身特點:
該對象的目的地有四個:1:File對象。2:字符串路徑。3:字節輸出流。4:字符輸出流。 開發時儘量使用PrintWriter。

26. SequenceInputStream:序列流,作用就是將多個讀取流合併成一個讀取流。實現數據合併。靜態不能被序列化。

27. 管道流:管道讀取流和管道寫入流可以像管道一樣對接上,管道讀取流就可以讀取管道寫入流寫入的數據。

28. ByteArrayOutputStream:目的:內存。 
這兩個流對象不涉及底層資源調用,操作的都是內存中數組,所以不需要關閉。

直接操作字節數組就可以了,爲什麼還要把數組封裝到流對象中呢?因爲數組本身沒有方法,只有一個length屬性。爲了便於數組的操作,將數組進行封裝,對外提供方法操作數組中的元素。

29. 轉換流的字符編碼

編碼: 字符串變成字節數組

解碼: 字節數組變成字符串

美國: Acinal碼   歐洲: iso8859-1 中國: GBK 統一的: unicode( UTF-8)

30. Tomcat 服務器默認編碼方式: iso8859-1
發佈了39 篇原創文章 · 獲贊 10 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章