IO流按操作數據分爲:字節流和字符流,流按流向分爲:輸入和輸出流。
字節流 | 字符流 | |
輸入流 | InputStream | Reader |
輸出流 | OutputStream | Writer |
字節流:操作的對象是媒體文件,字節流處理單元爲 1 個字節,操作字節和字節數組。
字符流:操作的對象是純文本的數據,字符流處理的單元爲 2 個字節的 Unicode 字符,分別操作字符、字符數組或字符串。
1、 流工作原理:
答案與水流原理基本一致,通過二進制方式輸入或輸出!
可以通過一個更強大的管道,將二進制值轉換爲其它形式!
2、 流的分類:
流的方向不同:輸入流、輸出流
流的單位不同:字節流、字符流
流的功能不同:節點流、處理流
3、 流的抽象類:
輸入:InputStream、Reader
輸出:OutputStream、Writer
4、 什麼是字節流、字符流
字節流:以字節爲單位傳輸(1字節==8位)
字符流:以字符爲單位傳輸 (1字符==2字節==16位)
5、 什麼是節點流、什麼是處理流
節點流:直接讀取程序的流(字節流)
處理流:對原始讀取流進行轉換其它格式的流(對數據進行過濾)
6、 常用流的具體分類:
字節輸入流:InputStream ↓
FileInputStream(以文件方式)
ByteArrayInputStream(以字節數組方式)
StringBufferInputStream(以字符傳方式)
ObjectInputStream(以對象方式)
字節輸出流:OutputStream ↓
FileOutputStream(以文件方式)
ByteArrayOutputStream(以字節數組方式)
ObjectOutputStream(以對象方式)
字符輸入流:Reader
BufferedReader(緩衝字符流)
CharArrayReader(字符數組方式)
InputStreamReader(以字節方式編譯到字符方式)
FileReader(以字符形式讀取文件方式)
StringReader(以源文件爲字符串的字符流方式)
7、 InputStream基本方法:
reader() 讀取方式,返回爲-1代表讀取完畢
close() 關閉流
OutputStream基本方法:
writer() 寫入數據
flush () 強制將緩衝區數據寫出
close() 關閉流
Reader基本方法與InputStream一至
Writer 基本方法與OutputStream 一至
字符流結構圖:
InputStream和OutputStream是兩個抽象類,以字節爲導向的Stream都擴展這兩個基類。
1、 FileInputStream: 從文件系統中的某個文件中獲得輸入字節, 用於讀取諸如圖像數據之類的原始字節流。要讀取字符流,請考慮使用FileReader
。
2、 ByteArrayInputStream:用於操作字節數組的輸入流對象,而數據源是個字節數組
3、 FileterInputStream
FilterInputStream
包含其他一些輸入流,它將這些流用作其基本數據源,它可以直接傳輸數據或提供一些額外的功能。FilterInputStream
類本身只是簡單地重寫那些將所有請求傳遞給所包含輸入流的InputStream
的所有方法。FilterInputStream
的子類可進一步重寫這些方法中的一些方法,並且還可以提供一些額外的方法和字段
|-----------DataInputStream用於操作最基本的數據類型的流對象
|-----------BufferedInputStream,爲另一個流添加一些功能,創建對象時會創建一個緩衝區,內部封裝了數組。
|-----------LineNumberInputStream跟蹤行號的緩衝字符輸入流,此類定義了方法 setLineNumber(int)
和getLineNumber()
,它們可分別用於設置和獲取當前行號。
|-----------PushbackInputStream
4、 ObjectInputStream,操作對象的序列化的流,操作的對象必須實現Serializable接口(此接口中沒有任何方法,稱爲定義接口)。
操作的對象靜態屬性是不能被序列化,因爲序列化的屬性在堆裏面,而靜態在方法區。
對靜態的屬性,不想序列化,必須在屬性前面定義transient修飾符,transient修飾的屬性保證在堆內存存在,而不在文本中存在。
5、PipedInputStream:
管道流,輸入輸出可以直接進行連接,通過結合線程使用以前我們操作流的時候,輸出流和輸入流是沒有關係的,讀寫文件時要有一箇中轉站(緩衝區例如byte數組)但管道流的輸入流和輸出流是連接的,就像一個管道的兩端。
API管道流介紹:
管道輸入流應該連接到管道輸出流;管道輸入流提供要寫入管道輸出流的所有數據字節。通常,數據由某個線程從 PipedInputStream 對象讀取,並由其他線程將其寫入到相應的 PipedOutputStream。不建議對這兩個對象嘗試使用單個線程,因爲這樣可能死鎖線程。管道輸入流包含一個緩衝區,可在緩衝區限定的範圍內將讀操作和寫操作分離開。如果向連接管道輸出流提供數據字節的線程不再存在,則認爲該管道已損壞。
6、sequenceInputStream:序列流,可以對多個流進行合併。
7、StringBufferInputStream:
這個類以過時、此類允許應用程序創建輸入流,在該流中讀取的字節由字符串內容提供。應用程序還可以使用 ByteArrayInputStream
從 byte 數組中讀取字節
8、PrintStream:該流提供了打印方法,可以將各種數據類型的數據都原樣打印
字節打印流:PrintStream
構造函數可以接收的參數類型:
1、file對象 File
2、字符串路徑 String
3、字節輸出流 OutputStream
字符流結構圖:
1、BufferedReader
從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。可以指定緩衝區的大小,或者可使用默認的大小。大多數情況下,默認值就足夠大了
|---LineNumberReader
跟蹤行號的緩衝字符輸入流。此類定義了方法
setLineNumber(int)
和getLineNumber()
,它們可分別用於設置和獲取當前行號。
2、CharArrayReader
此類可以實現一個可用作字符輸入流的的字符緩衝區。
3、InputStreamReader轉換流:
|---FileReader: 字符輸入打印流
FileWriter:字符輸出打印流
4、FilterReader
|---PushbackReader
5、PipedReader:字符管道流。
6、StringReader其源爲一個字符串的字符流,讀取字符串的流對象。
RandomAccessFile不算IO體系中的子類,而是直接繼承Object,但是它IO包中的成員
因爲它具備讀和寫功能,內部封裝了一個數組,而且通過指針,對數組中的元素進行操作。
可以通過getFilePionter獲取指針位置,同時可以通過seek改變指針的位置.
其實完成讀寫的原理,就是內部封裝了字節輸入流和字節輸出流。
通過構造函數可以看出,該類只能操作文件。
而且操作文件還有模式。
通過構造函數可以看出,該類只能操作文件。而且操作文件還有模式,只讀r,讀寫,rw等、
如果模式爲只讀r的話,不會創建文件,會去讀取一個已存在的文件,如果該文件不存在,則會
出現異常。
如果模式爲rw、那麼操作的文件不存在則會創建。如果存在則不會覆蓋。
Java IO 的一般使用原則 :
一、按數據來源(去向)分類:
1 、是文件: FileInputStream, FileOutputStream, ( 字節流 )FileReader, FileWriter( 字符 )
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字節流 )
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字節流 )StringReader, StringWriter( 字符流 )
5 、網絡數據流: InputStream, OutputStream,( 字節流 ) Reader, Writer( 字符流 )
二、按是否格式化輸出分:
1 、要格式化輸出: PrintStream, PrintWriter
三、按是否要緩衝分:
1 、要緩衝: BufferedInputStream, BufferedOutputStream,( 字節流 ) BufferedReader, BufferedWriter( 字符流 )
四、按數據格式分:
1 、二進制格式(只要不能確定是純文本的) : InputStream, OutputStream 及其所有帶 Stream 結束的子類
2 、純文本格式(含純英文與漢字或其他編碼方式); Reader, Writer 及其所有帶 Reader, Writer 的子類
五、按輸入輸出分:
1 、輸入: Reader, InputStream 類型的子類
2 、輸出: Writer, OutputStream 類型的子類
六、特殊需要:
1 、從 Stream 到 Reader,Writer 的轉換類: InputStreamReader, OutputStreamWriter
2 、對象輸入輸出: ObjectInputStream, ObjectOutputStream
3 、進程間通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4 、合併輸入: SequenceInputStream
5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader
決定使用哪個類以及它的構造進程的一般準則如下(不考慮特殊需要):
首先,考慮最原始的數據格式是什麼: 原則四
第二,是輸入還是輸出:原則五
第三,是否需要轉換流:原則六第 1 點
第四,數據來源(去向)是什麼:原則一
第五,是否要緩衝:原則三 (特別註明:一定要注意的是 readLine() 是否有定義,有什麼比 read, write 更特殊的輸入或輸出方法)
第六,是否要格式化輸出:原則二