Java I/O庫的設(shè)計原則
?
Java的I/O庫提供了一個稱做鏈接的機(jī)制,可以將一個流與另一個流首尾相接,形成一個流管道的鏈接。這種機(jī)制實際上是一種被稱為Decorator(裝飾)設(shè)計模式的應(yīng)用。
通過流的鏈接,可以動態(tài)的增加流的功能,而這種功能的增加是通過組合一些流的基本功能而動態(tài)獲取的。
我們要獲取一個I/O對象,往往需要產(chǎn)生多個I/O對象,這也是Java I/O庫不太容易掌握的原因,但在I/O庫中Decorator模式的運(yùn)用,給我們提供了實現(xiàn)上的靈活性。
?
I/O流的鏈接
Reader和Writer
Java程序語言使用Unicode來表示字符串和字符。
Reader和Writer這兩個抽象類主要用來讀寫字符流。
?
java.io包中Reader的類層次
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 Reader
java.lang.Object
? java.io.Reader
所有已實現(xiàn)的接口:
Closeable, Readable
直接已知子類:
BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader
public abstract class Reader
extends Object
implements Readable, Closeable
用于讀取字符流的抽象類。子類必須實現(xiàn)的方法只有 read(char[], int, int) 和 close()。但是,多數(shù)子類將重寫此處定義的一些方法,以提供更高的效率和/或其他功能。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 BufferedReader
java.lang.Object
? java.io.Reader
????? java.io.BufferedReader
所有已實現(xiàn)的接口:
Closeable, Readable
直接已知子類:
LineNumberReader
public class BufferedReader
extends Reader
從字符輸入流中讀取文本,緩沖各個字符,從而提供字符、數(shù)組和行的高效讀取。
可以指定緩沖區(qū)的大小,或者可使用默認(rèn)的大小。大多數(shù)情況下,默認(rèn)值就足夠大了。
通常,Reader 所作的每個讀取請求都會導(dǎo)致對基礎(chǔ)字符或字節(jié)流進(jìn)行相應(yīng)的讀取請求。因此,建議用 BufferedReader 包裝所有其 read() 操作可能開銷很高的 Reader(如 FileReader 和 InputStreamReader)。例如,
?BufferedReader in
?? = new BufferedReader(new FileReader("foo.in"));
?
將緩沖指定文件的輸入。如果沒有緩沖,則每次調(diào)用 read() 或 readLine() 都會導(dǎo)致從文件中讀取字節(jié),并將其轉(zhuǎn)換為字符后返回,而這是極其低效的。
可以對使用 DataInputStream 進(jìn)行按原文輸入的程序進(jìn)行本地化,方法是用合適的 BufferedReader 替換每個 DataInputStream。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 InputStreamReader
java.lang.Object
? java.io.Reader
????? java.io.InputStreamReader
所有已實現(xiàn)的接口:
Closeable, Readable
直接已知子類:
FileReader
public class InputStreamReader
extends Reader
InputStreamReader 是字節(jié)流通向字符流的橋梁:它使用指定的 charset 讀取字節(jié)并將其解碼為字符。它使用的字符集可以由名稱指定或顯式給定,否則可能接受平臺默認(rèn)的字符集。
每次調(diào)用 InputStreamReader 中的一個 read() 方法都會導(dǎo)致從基礎(chǔ)輸入流讀取一個或多個字節(jié)。要啟用從字節(jié)到字符的有效轉(zhuǎn)換,可以提前從基礎(chǔ)流讀取更多的字節(jié),使其超過滿足當(dāng)前讀取操作所需的字節(jié)。
為了達(dá)到最高效率,可要考慮在 BufferedReader 內(nèi)包裝 InputStreamReader。例如:
?BufferedReader in
?? = new BufferedReader(new InputStreamReader(System.in));
?
從以下版本開始:
JDK1.1
java.io包中Writer的類層次
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 Writer
java.lang.Object
? java.io.Writer
所有已實現(xiàn)的接口:
Closeable, Flushable, Appendable
直接已知子類:
BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter
public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable
寫入字符流的抽象類。子類必須實現(xiàn)的方法僅有 write(char[], int, int)、flush() 和 close()。但是,多數(shù)子類將重寫此處定義的一些方法,以提供更高的效率和/或其他功能。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 BufferedWriter
java.lang.Object
? java.io.Writer
????? java.io.BufferedWriter
所有已實現(xiàn)的接口:
Closeable, Flushable, Appendable
public class BufferedWriter
extends Writer
將文本寫入字符輸出流,緩沖各個字符,從而提供單個字符、數(shù)組和字符串的高效寫入。
可以指定緩沖區(qū)的大小,或者接受默認(rèn)的大小。在大多數(shù)情況下,默認(rèn)值就足夠大了。
該類提供了 newLine() 方法,它使用平臺自己的行分隔符概念,此概念由系統(tǒng)屬性 line.separator 定義。并非所有平臺都使用新行符 ('\n') 來終止各行。因此調(diào)用此方法來終止每個輸出行要優(yōu)于直接寫入新行符。
通常 Writer 將其輸出立即發(fā)送到基礎(chǔ)字符或字節(jié)流。除非要求提示輸出,否則建議用 BufferedWriter 包裝所有其 write() 操作可能開銷很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,
?PrintWriter out
?? = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
?
將緩沖 PrintWriter 對文件的輸出。如果沒有緩沖,則每次調(diào)用 print() 方法會導(dǎo)致將字符轉(zhuǎn)換為字節(jié),然后立即寫入到文件,而這是極其低效的。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 OutputStreamWriter
java.lang.Object
? java.io.Writer
????? java.io.OutputStreamWriter
所有已實現(xiàn)的接口:
Closeable, Flushable, Appendable
直接已知子類:
FileWriter
public class OutputStreamWriter
extends Writer
OutputStreamWriter 是字符流通向字節(jié)流的橋梁:使用指定的 charset 將要向其寫入的字符編碼為字節(jié)。它使用的字符集可以由名稱指定或顯式給定,否則可能接受平臺默認(rèn)的字符集。
每次調(diào)用 write() 方法都會針對給定的字符(或字符集)調(diào)用編碼轉(zhuǎn)換器。在寫入基礎(chǔ)輸出流之前,得到的這些字節(jié)會在緩沖區(qū)累積。可以指定此緩沖區(qū)的大小,不過,默認(rèn)的緩沖區(qū)對多數(shù)用途來說已足夠大。注意,傳遞到此 write() 方法的字符是未緩沖的。
為了達(dá)到最高效率,可考慮將 OutputStreamWriter 包裝到 BufferedWriter 中以避免頻繁調(diào)用轉(zhuǎn)換器。例如:
?Writer out
?? = new BufferedWriter(new OutputStreamWriter(System.out));
?
代理對 是一個字符,它由兩個 char 值序列表示:高 代理項的范圍為 '\uD800' 到 '\uDBFF',它后面跟著范圍為 '\uDC00' 到 '\uDFFF' 的低 代理項。如果由代理項對表示的字符無法由給定的字符集編碼,則把依賴于字符集的替代序列 寫入輸出流。
錯誤代理元素 指的是后面不跟低代理項的高代理項,或前面沒有高代理項的低代理項。嘗試寫入包含錯誤代理元素的字符流是非法的。寫入錯誤代理元素時,此類實例的行為是不確定的。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo1:通過字符流將字符串寫入指定文件。
-------------------------------------------------------------------------------

?2

?3



?4

?5



?6

?7

?8

?9

10

11

12

13

14

15

-------------------------------------------------------------------------------
運(yùn)行結(jié)果:字符串"-------------------------------------------------------------------------------
Demo2:通過字符流將字符串寫入指定文件,同時讀取字符流。
-------------------------------------------------------------------------------

?2

?3



?4

?5



?6

?7

?8

?9

10

11

12

13

14

15

16

17

18

19

20

21

-------------------------------------------------------------------------------
運(yùn)行結(jié)果:字符串"???然后被讀取出來。
-------------------------------------------------------------------------------
Demo3:通過字符流接收數(shù)據(jù),然后輸出到控制臺。
-------------------------------------------------------------------------------

?2

?3



?4

?5



?6

?7

?8

?9

10

11



12

13

14

15

16

17

18

-------------------------------------------------------------------------------
運(yùn)行結(jié)果:控制臺輸出輸入的內(nèi)容。
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo4:通過字符流接收數(shù)據(jù),然后輸出到控制臺,同時將輸入內(nèi)容寫入
??指定的文件中。
-------------------------------------------------------------------------------

?2

?3



?4

?5



?6

?7

?8

?9

10

11

12

13

14

15

16



17

18

19

20

21

22

23

24

25

26

-------------------------------------------------------------------------------
運(yùn)行結(jié)果:控制臺輸出輸入的內(nèi)容,同時輸入的內(nèi)容被寫入指定的文件中。
-------------------------------------------------------------------------------