1、流式輸入與輸出
爲進行數據的輸入、輸出操作,Java中把不同的輸入、輸出源(鍵盤、文件、網絡連接等)抽象爲“流”(Stream),有兩種基本的流:輸入流和輸出流。
(1)輸入流:只能從中讀取數據,而不能向其寫出數據。
(2)輸出流:只能向其寫出數據,而不能從中讀取數據。
流實際上指在計算機的輸入與輸出之間運動的數據的序列,流序列中的數據既可以是未經加工的原始二進制數據,也可以是經一定編碼處理後符合某種格式規定的特定數據,如字符流序列、數字流序列等。
1.1、字節流與字符流
按處理數據的類型,流可以分爲字節流和字符流,它們處理的信息的基本單位分別是字節(byte)與字符(char)。
輸入字節流的類爲InputStream
輸出字節流的類爲OutputStream
輸入字符流的類爲Reader
輸出字符流的類爲Writer
如下表,這四個類是抽象類,其他的輸入輸出流類都是它們的子類。
字節流與字符流
|
字節流 |
字符流 |
輸入 |
InputStream |
Reader |
輸出 |
OutputStream |
Writer |
方法摘要 | |
---|---|
int |
available() 返回此輸入流方法的下一個調用方可以不受阻塞地從此輸入流讀取(或跳過)的字節數。 |
void |
close() 關閉此輸入流並釋放與該流關聯的所有系統資源。 |
void |
mark(int readlimit) 在此輸入流中標記當前的位置。 |
boolean |
markSupported() 測試此輸入流是否支持 mark 和 reset 方法。 |
abstract int |
read() 從輸入流讀取下一個數據字節。 |
int |
read(byte[] b) 從輸入流中讀取一定數量的字節並將其存儲在緩衝區數組 b 中,以整數形式返回實際讀取的字節數。 |
int |
read(byte[] b, int off, int len) 將輸入流中最多 len 個數據字節讀入字節數組,將讀取的第一個字節存儲在元素 b[off] 中,下一個存儲在 b[off+1] 中,依次類推。讀取的字節數最多等於 len 。 |
void |
reset() 將此流重新定位到對此輸入流最後調用 mark 方法時的位置。 |
long |
skip(long n) 跳過和放棄此輸入流中的 n 個數據字節。 |
OutputStream類
此抽象類是表示輸出字節流的所有類的超類。輸出流接受輸出字節並將這些字節發送到某個接收器。
方法摘要 | |
---|---|
void |
close() 關閉此輸出流並釋放與此流有關的所有系統資源。 |
void |
flush() 刷新此輸出流並強制寫出所有緩衝的輸出字節。 |
void |
write(byte[] b) 將 b.length 個字節從指定的字節數組寫入此輸出流。 |
void |
write(byte[] b, int off, int len) 將指定字節數組中從偏移量 off 開始的 len 個字節寫入此輸出流。 |
abstract void |
write(int b) 將指定的字節寫入此輸出流。 |
將指定的字節寫入此輸出流。write 的常規協定是:向輸出流寫入一個字節。要寫入的字節是參數 b 的八個低位。b 的 24 個高位將被忽略。 OutputStream 的子類必須提供此方法的實現。
flush()方法刷新緩衝區的內容。對於緩衝流式輸出來說,write()方法所寫的數據並沒有直接傳到與輸出流相連的外部設備上,而是先暫時存放在流的緩衝區中,等到緩衝區中的數據積累到一定數量,再統一執行一次向外部設備的寫操作把它們全部寫到外部設備上。這樣處理可以降低計算機對外部設備的讀寫次數,大大提高系統的效率。但是在某些情況下,緩衝區中的數據不滿時就需要將它寫到外部設備上,此時應使用強制清空緩衝區並執行外部設備寫操作的flush()方法。
Reader類
Reader類與InputStream類相似,都是輸入流,但差別在於Reader類讀入的是字符(char),而不是字節。
方法摘要 | |
---|---|
abstract void |
close() 關閉該流。 |
void |
mark(int readAheadLimit) 標記流中的當前位置。 |
boolean |
markSupported() 判斷此流是否支持 mark() 操作。 |
int |
read() 讀取單個字符。 |
int |
read(char[] cbuf) 將字符讀入數組。 |
abstract int |
read(char[] cbuf, int off, int len) 將字符讀入數組的某一部分。 |
int |
read(CharBuffer target) 試圖將字符讀入指定的字符緩衝區。 |
boolean |
ready() 判斷是否準備讀取此流。 |
void |
reset() 重置該流。 |
long |
skip(long n) 跳過字符。 |
方法摘要 | |
---|---|
Writer |
append(char c) 將指定字符追加到此 writer。 |
Writer |
append(CharSequence csq) 將指定字符序列追加到此 writer。 |
Writer |
append(CharSequence csq, int start, int end) 將指定字符序列的子序列追加到此 writer.Appendable。 |
abstract void |
close() 關閉此流,但要先刷新它。 |
abstract void |
flush() 刷新此流。 |
void |
write(char[] cbuf) 寫入字符數組。 |
abstract void |
write(char[] cbuf, int off, int len) 寫入字符數組的某一部分。 |
void |
write(int c) 寫入單個字符。 |
void |
write(String str) 寫入字符串。 |
void |
write(String str, int off, int len) 寫入字符串的某一部分。 |
1、2節點流和處理流
按照流是否直接與特定的地方(如磁盤、內存、設備等)相連,分爲節點流與處理流兩類。
(1)節點流(Node Stream):可以從或向一個特定的地方(節點)讀寫數據。如文件流FileReader
(2)處理流(Processing Stream):是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫功能。處理流又稱爲過濾流,如緩衝處理流BufferReader。
節點流與處理流的關係:節點流直接與節點(如文件)相連,而處理流對節點流或其他處理流進一步進行處理(如緩衝、組裝成對象,等等)。
處理流的構造方法總是要帶一個其他流對象作爲參數。 如:
BufferedReader iin = new BufferedReader(new FileReader(file));
常用的節點流:
節點類型 | 節點流 | 字符流 |
File文件 |
FileInputStream FileOutputStream |
FileReader FileWriter |
Memory Array內存數組 |
ByteArrayInputStream ByteArrayOutputStream |
CharArrayReader CharArrayWriter |
Memory String字符串 |
StringReader StringWriter |
|
Pipe管道 |
PipedInputStream PipedOutputStream |
PipedReader PipedWriter |
常用的處理流
處理類型 | 字節流 | 字符流 |
Buffering緩衝 |
BufferedInputStream BufferedOutputStream |
BufferedReader BufferedWriter |
Filtering過濾 |
FilterInputStream FilterOutputStream |
FilterReader FilterWirter |
Converting between bytes and character 字節流轉爲字符流 |
InputStreamReader OutputStreamWriter |
|
Object Serialization 對象序列化 |
ObjectInputStream ObjectOutputStream |
|
Date coversion 基本數據類型轉化 |
DateInputStream DateOutputStream |
|
Counting行號處理 |
LineNumberInputStream | LineNumberReader |
Peeking ahead可回退流 |
PushBackInputStream | PushbackReader |
Pinting可顯示處理 | PrintStream | PrintWriter |
從抽象類Reader和Writer中也派生出一些子類,這些子類使InputStream和OutputStream的以字節爲單位輸入、輸出轉換爲以字符爲單位輸入、輸出,使用起來比InputStream和OutputStream要方便很多。
數據輸入、輸出流DataInputStream和DataOutputStream分別是過濾輸入、輸出流FilterInputStream和FilterOutputStream的子類。過濾輸入、輸出流的最主要作用就是在數據源和程序之間加一個過濾處理步驟,對原始數據做特定的加工、處理和變換操作。
標準輸入和標準輸出
當java程序需要與外界數據源做輸入、輸出的數據交換時,它需要首先創建一個輸入或輸出類的對象來完成對這個數據源的連接。例如,當java程序需要讀寫文件時,它需要先創建文件的輸入或文件輸出流類的對象。除文件外,程序也經常使用字符界面的標準輸入、輸出設備進行讀寫操作。
計算機系統都有默認的標準輸入設備和標準輸出設備。對一般的系統,標準輸入通常是鍵盤,標準輸出通常是顯示器屏幕。Java程序使用字符界面與系統標準輸入、輸出間進行數據通信,即從鍵盤讀入數據,或向屏幕輸出數據,是十分常見的操作,爲此而頻頻創建輸入、輸出流類對象將很不方便。爲此java系統事先定義好兩個流對象,分別與系統的標準輸入和標準輸出相聯繫,它們是System.in和System.out