Java I/O庫的設計原則
?
Java的I/O庫提供了一個稱做鏈接的機制,可以將一個流與另一個流首尾相接,形成一個流管道的鏈接。這種機制實際上是一種被稱為Decorator(裝飾)設計模式的應用。
通過流的鏈接,可以動態的增加流的功能,而這種功能的增加是通過組合一些流的基本功能而動態獲取的。
我們要獲取一個I/O對象,往往需要產生多個I/O對象,這也是Java I/O庫不太容易掌握的原因,但在I/O庫中Decorator模式的運用,給我們提供了實現上的靈活性。
?
I/O流的鏈接
Reader和Writer
Java程序語言使用Unicode來表示字符串和字符。
Reader和Writer這兩個抽象類主要用來讀寫字符流。
?
java.io包中Reader的類層次

-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 Reader
java.lang.Object
? java.io.Reader
所有已實現的接口:
Closeable, Readable
直接已知子類:
BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader
public abstract class Reader
extends Object
implements Readable, Closeable
用于讀取字符流的抽象類。子類必須實現的方法只有 read(char[], int, int) 和 close()。但是,多數子類將重寫此處定義的一些方法,以提供更高的效率和/或其他功能。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 BufferedReader
java.lang.Object
? java.io.Reader
????? java.io.BufferedReader
所有已實現的接口:
Closeable, Readable
直接已知子類:
LineNumberReader
public class BufferedReader
extends Reader
從字符輸入流中讀取文本,緩沖各個字符,從而提供字符、數組和行的高效讀取。
可以指定緩沖區的大小,或者可使用默認的大小。大多數情況下,默認值就足夠大了。
通常,Reader 所作的每個讀取請求都會導致對基礎字符或字節流進行相應的讀取請求。因此,建議用 BufferedReader 包裝所有其 read() 操作可能開銷很高的 Reader(如 FileReader 和 InputStreamReader)。例如,
?BufferedReader in
?? = new BufferedReader(new FileReader("foo.in"));
?
將緩沖指定文件的輸入。如果沒有緩沖,則每次調用 read() 或 readLine() 都會導致從文件中讀取字節,并將其轉換為字符后返回,而這是極其低效的。
可以對使用 DataInputStream 進行按原文輸入的程序進行本地化,方法是用合適的 BufferedReader 替換每個 DataInputStream。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 InputStreamReader
java.lang.Object
? java.io.Reader
????? java.io.InputStreamReader
所有已實現的接口:
Closeable, Readable
直接已知子類:
FileReader
public class InputStreamReader
extends Reader
InputStreamReader 是字節流通向字符流的橋梁:它使用指定的 charset 讀取字節并將其解碼為字符。它使用的字符集可以由名稱指定或顯式給定,否則可能接受平臺默認的字符集。
每次調用 InputStreamReader 中的一個 read() 方法都會導致從基礎輸入流讀取一個或多個字節。要啟用從字節到字符的有效轉換,可以提前從基礎流讀取更多的字節,使其超過滿足當前讀取操作所需的字節。
為了達到最高效率,可要考慮在 BufferedReader 內包裝 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
所有已實現的接口:
Closeable, Flushable, Appendable
直接已知子類:
BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter
public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable
寫入字符流的抽象類。子類必須實現的方法僅有 write(char[], int, int)、flush() 和 close()。但是,多數子類將重寫此處定義的一些方法,以提供更高的效率和/或其他功能。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 BufferedWriter
java.lang.Object
? java.io.Writer
????? java.io.BufferedWriter
所有已實現的接口:
Closeable, Flushable, Appendable
public class BufferedWriter
extends Writer
將文本寫入字符輸出流,緩沖各個字符,從而提供單個字符、數組和字符串的高效寫入。
可以指定緩沖區的大小,或者接受默認的大小。在大多數情況下,默認值就足夠大了。
該類提供了 newLine() 方法,它使用平臺自己的行分隔符概念,此概念由系統屬性 line.separator 定義。并非所有平臺都使用新行符 ('\n') 來終止各行。因此調用此方法來終止每個輸出行要優于直接寫入新行符。
通常 Writer 將其輸出立即發送到基礎字符或字節流。除非要求提示輸出,否則建議用 BufferedWriter 包裝所有其 write() 操作可能開銷很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,
?PrintWriter out
?? = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
?
將緩沖 PrintWriter 對文件的輸出。如果沒有緩沖,則每次調用 print() 方法會導致將字符轉換為字節,然后立即寫入到文件,而這是極其低效的。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 OutputStreamWriter
java.lang.Object
? java.io.Writer
????? java.io.OutputStreamWriter
所有已實現的接口:
Closeable, Flushable, Appendable
直接已知子類:
FileWriter
public class OutputStreamWriter
extends Writer
OutputStreamWriter 是字符流通向字節流的橋梁:使用指定的 charset 將要向其寫入的字符編碼為字節。它使用的字符集可以由名稱指定或顯式給定,否則可能接受平臺默認的字符集。
每次調用 write() 方法都會針對給定的字符(或字符集)調用編碼轉換器。在寫入基礎輸出流之前,得到的這些字節會在緩沖區累積。可以指定此緩沖區的大小,不過,默認的緩沖區對多數用途來說已足夠大。注意,傳遞到此 write() 方法的字符是未緩沖的。
為了達到最高效率,可考慮將 OutputStreamWriter 包裝到 BufferedWriter 中以避免頻繁調用轉換器。例如:
?Writer out
?? = new BufferedWriter(new OutputStreamWriter(System.out));
?
代理對 是一個字符,它由兩個 char 值序列表示:高 代理項的范圍為 '\uD800' 到 '\uDBFF',它后面跟著范圍為 '\uDC00' 到 '\uDFFF' 的低 代理項。如果由代理項對表示的字符無法由給定的字符集編碼,則把依賴于字符集的替代序列 寫入輸出流。
錯誤代理元素 指的是后面不跟低代理項的高代理項,或前面沒有高代理項的低代理項。嘗試寫入包含錯誤代理元素的字符流是非法的。寫入錯誤代理元素時,此類實例的行為是不確定的。
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo1:通過字符流將字符串寫入指定文件。
-------------------------------------------------------------------------------
?1
import
?java.io.
*
;
?2
?3
public
?
class
?CharStream?
{
?4
?5
?
public
?
static
?
void
?main(String[]?args)?
throws
?Exception?
{
?6
?7
??FileOutputStream?fos?
=
?
new
?FileOutputStream(
"
write.txt
"
);
?8
??OutputStreamWriter?osw?
=
?
new
?OutputStreamWriter(fos);
?9
??BufferedWriter?bw?
=
?
new
?BufferedWriter(osw);
10
11
??bw.write(
"
http://www.blogjava.com
"
);
12
??bw.close();
13
?}
14
15
}
-------------------------------------------------------------------------------
運行結果:字符串"-------------------------------------------------------------------------------
Demo2:通過字符流將字符串寫入指定文件,同時讀取字符流。
-------------------------------------------------------------------------------
?1
import
?java.io.
*
;
?2
?3
public
?
class
?CharStream?
{
?4
?5
?
public
?
static
?
void
?main(String[]?args)?
throws
?Exception?
{
?6
?7
??FileOutputStream?fos?
=
?
new
?FileOutputStream(
"
write.txt
"
);
?8
??OutputStreamWriter?osw?
=
?
new
?OutputStreamWriter(fos);
?9
??BufferedWriter?bw?
=
?
new
?BufferedWriter(osw);
10
11
??bw.write(
"
http://www.blogjava.com
"
);
12
??bw.close();
13
??
14
??FileInputStream?fis?
=
?
new
?FileInputStream(
"
write.txt
"
);
15
??InputStreamReader?isr?
=
?
new
?InputStreamReader(fis);
16
??BufferedReader?br?
=
?
new
?BufferedReader(isr);
17
??System.out.println(br.readLine());
18
??br.close();
19
?}
20
21
}
-------------------------------------------------------------------------------
運行結果:字符串"???然后被讀取出來。
-------------------------------------------------------------------------------
Demo3:通過字符流接收數據,然后輸出到控制臺。
-------------------------------------------------------------------------------
?1
import
?java.io.
*
;
?2
?3
public
?
class
?CharStream?
{
?4
?5
?
public
?
static
?
void
?main(String[]?args)?
throws
?Exception?
{
?6
?7
??InputStreamReader?isr?
=
?
new
?InputStreamReader(System.in);
?8
??BufferedReader?br?
=
?
new
?BufferedReader(isr);
?9
??
10
??String?strLine?
=
?
null
;?
//
?定義一個對象后最好先將它初始化
11
??
while
?((strLine?
=
?br.readLine())?
!=
?
null
)?
{
12
???System.out.println(strLine);
13
??}
14
??
15
??br.close();
16
?}
17
18
}
-------------------------------------------------------------------------------
運行結果:控制臺輸出輸入的內容。
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo4:通過字符流接收數據,然后輸出到控制臺,同時將輸入內容寫入
??指定的文件中。
-------------------------------------------------------------------------------
?1
import
?java.io.
*
;
?2
?3
public
?
class
?CharStream?
{
?4
?5
?
public
?
static
?
void
?main(String[]?args)?
throws
?Exception?
{
?6
?7
??FileOutputStream?fos?
=
?
new
?FileOutputStream(
"
write1.txt
"
);
?8
??OutputStreamWriter?osw?
=
?
new
?OutputStreamWriter(fos);
?9
??BufferedWriter?bw?
=
?
new
?BufferedWriter(osw);
10
??
11
??InputStreamReader?isr?
=
?
new
?InputStreamReader(System.in);
12
??BufferedReader?br?
=
?
new
?BufferedReader(isr);
13
??
14
??String?strLine?
=
?
null
;?
//
?定義一個對象后最好先將它初始化
15
16
??
while
?(
!
(strLine?
=
?br.readLine()).equals(
"
exit
"
))?
{
17
???System.out.println(strLine);
18
???bw.write(strLine);
19
???bw.write(
"
\n
"
);
20
??}
21
??
22
??bw.close();
23
??br.close();
24
?}
25
26
}
-------------------------------------------------------------------------------
運行結果:控制臺輸出輸入的內容,同時輸入的內容被寫入指定的文件中。
-------------------------------------------------------------------------------
posted on 2006-08-24 20:01
CoderDream 閱讀(1268)
評論(0) 編輯 收藏 所屬分類:
Java基礎知識