java中的流,可以從不同的角度進行分類。
輸入流: 程式可以從中讀取資料的流。
輸出流: 程式能向其中寫入資料的流。
位元組流:以位元組(8位二進制)為機關進行處理。主要用于讀寫諸如圖像或聲音的二進制資料。
字元流:以字元(16位二進制)為機關進行處理。
都是通過位元組流的方式實作的。字元流是對位元組流進行了封裝,友善操作。在最底層,所有的輸入輸出都是位元組形式的。
字尾是stream是位元組流,而字尾是reader,writer是字元流。
節點流:從特定的地方讀寫的流類,如磁盤或者一塊記憶體區域。
過濾流:使用節點流作為輸入或輸出。過濾流是使用一個已經存在的輸入流或者輸出流連接配接建立的。
jdk提供的流繼承了四大類:inputstream(位元組輸入流),outputstream(位元組輸出流),reader(字元輸入流),writer(字元輸出流)。
位元組輸入流抽象類及其關鍵的方法:
類 inputstream
1
2
<code>java.io.inputstream</code>
<code>abstract</code> <code>int</code> <code>read()</code>
從輸入流中讀取資料的下一個位元組。
<code>int</code> <code>read(</code><code>byte</code><code>[] b)</code>
從輸入流中讀取一定數量的位元組,并将其存儲在緩沖區數組 b 中。
<code>int</code> <code>read(</code><code>byte</code><code>[] b, </code><code>int</code> <code>off, </code><code>int</code> <code>len)</code>
将輸入流中最多 len 個資料位元組讀入 byte 數組。
輸入流的操作:
打開一個輸入流
循環讀取
關閉輸入流
這裡使用inputstream的子類fileinputstream讀入檔案:
3
4
5
6
7
8
9
10
11
12
13
14
<code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) </code><code>throws</code> <code>ioexception {</code>
<code> </code><code>//建立檔案輸入流</code>
<code> </code><code>inputstream is = </code><code>new</code> <code>fileinputstream(</code><code>"d:/itzhai/arthinking.txt"</code><code>);</code>
<code> </code><code>//建立位元組緩沖</code>
<code> </code><code>byte</code><code>[] buffer = </code><code>new</code> <code>byte</code><code>[</code><code>100</code><code>];</code>
<code> </code><code>int</code> <code>length = </code><code>0</code><code>;</code>
<code> </code><code>//以位元組形式循環讀取檔案</code>
<code> </code><code>while</code><code>((length = is.read(buffer, </code><code>0</code><code>, buffer.length)) != -</code><code>1</code><code>){</code>
<code> </code><code>//把位元組轉換成字元并輸出</code>
<code> </code><code>string str =</code><code>new</code> <code>string(buffer, </code><code>0</code><code>, length);</code>
<code> </code><code>system.out.println(str);</code>
<code> </code><code>}</code>
<code>}</code>
抽象類inputstream的類層次:
位元組數組輸入流bytearrayinputstream
把位元組數組作為源的輸入流。
相關例子:
位元組數組輸入流:
15
16
17
18
19
<code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>
<code> </code><code>//建立讀取資料源</code>
<code> </code><code>string input = </code><code>"arthinking"</code><code>;</code>
<code> </code><code>//擷取位元組數組</code>
<code> </code><code>byte</code><code>[] b = input.getbytes();</code>
<code> </code><code>//建立位元組數組輸出流</code>
<code> </code><code>bytearrayinputstream bis = </code><code>new</code> <code>bytearrayinputstream(b);</code>
<code> </code><code>//循環逐個讀取</code>
<code> </code><code>for</code><code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i < input.length(); i++){</code>
<code> </code><code>int</code> <code>c;</code>
<code> </code><code>//讀取下一個位元組</code>
<code> </code><code>while</code><code>((c = bis.read()) != -</code><code>1</code><code>){</code>
<code> </code><code>system.out.print((</code><code>char</code><code>)c);</code>
<code> </code><code>}</code>
<code> </code><code>//将緩沖區的位置重置為标記位置</code>
<code> </code><code>bis.reset();</code>
位元組數組輸出流:
<code> </code><code>//建立位元組輸出流</code>
<code> </code><code>bytearrayoutputstream bos = </code><code>new</code> <code>bytearrayoutputstream();</code>
<code> </code><code>string output = </code><code>"arthinking"</code><code>;</code>
<code> </code><code>//建立需要輸出的位元組數組</code>
<code> </code><code>byte</code><code>[] buffer = output.getbytes();</code>
<code> </code><code>//把位元組數組寫到輸出流</code>
<code> </code><code>bos.write(buffer);</code>
<code> </code><code>//建立檔案輸出流</code>
<code> </code><code>outputstream os = </code><code>new</code> <code>fileoutputstream(</code><code>"d:/itzhai/arthinking.txt"</code><code>);</code>
<code> </code><code>//把位元組輸出流寫到檔案輸出流</code>
<code> </code><code>bos.writeto(os);</code>
位元組輸出流的抽象類及其最關鍵的方法:
<code>類 outputstream</code>
<code>java.lang.object</code>
<code>java.io.outputstream</code>
<code>void</code> <code>write(</code><code>byte</code><code>[] b)</code>
将 b.length 個位元組從指定的 byte 數組寫入此輸出流。
<code>void</code> <code>write(</code><code>byte</code><code>[] b, </code><code>int</code> <code>off, </code><code>int</code> <code>len)</code>
将指定 byte 數組中從偏移量 off 開始的 len 個位元組寫入此輸出流。
<code>abstract</code> <code>void</code> <code>write(</code><code>int</code> <code>b)</code>
将指定的位元組寫入此輸出流。
由此可以看出,隻有最後一個方法才是抽象的,原因是前面兩個都調用了第三個抽象方法,這樣繼承這個抽象類的子類都必須提供抽象的write(int b)的實作,進而使得每個子類的實作都不一樣。
輸出流的操作:
打開輸出流
循環寫入
這裡使用了outputstream的子類fileoutputstream輸出到檔案:
<code> </code><code>//建立一個輸出流</code>
<code> </code><code>outputstream os = </code><code>new</code> <code>fileoutputstream(</code><code>"d:/itzhai/arthinking.txt"</code><code>, </code><code>true</code><code>);</code>
<code> </code><code>//從字元串中擷取位元組數組</code>
<code> </code><code>//寫出到輸出流</code>
<code> </code><code>os.write(buffer);</code>
<code> </code><code>//關閉輸出流</code>
<code> </code><code>os.close();</code>
抽象類outputstream的類層次結構:
過濾流:
過濾流不能直接跟檔案打交道,隻能通過節點流進行相關的操作。可以從其構造方法中看出:
<code>filteroutputstream(outputstream out)</code>
需要傳入一個outputstream。
在inputstream和outputstream的子類中,
filterinputstream和filteroutputstream是過濾流,其又派生出子類datainputstream和dataoutputstream資料輸入流和資料輸出流。
過濾流的主要特點是在輸入輸出資料同時對所傳輸的資料做指定類型或格式的轉換。
該類實作緩沖的輸出流。通過設定這種輸出流,應用程式就可以将各個位元組寫入底層輸出流中,而不必針對每次位元組寫入調用底層系統。
當緩沖區寫滿或者關閉輸出流時,一次性輸出到流,或者調用flush()方法主動将緩沖區輸出到流。
過濾流的使用例子:
使用過濾流類bufferedoutputstream和dataoutputstream裝飾filteroutputstream的例子:
20
21
22
<code> </code><code>//建立資料輸出流</code>
<code> </code><code>dataoutputstream dos = </code><code>new</code> <code>dataoutputstream(</code>
<code> </code><code>new</code> <code>bufferedoutputstream(</code><code>new</code> <code>fileoutputstream(</code><code>"d:/itzhai/arthinking.txt"</code><code>)));</code>
<code> </code><code>byte</code> <code>a = </code><code>1</code><code>;</code>
<code> </code><code>char</code> <code>b = </code><code>'a'</code><code>;</code>
<code> </code><code>int</code> <code>c = </code><code>2</code><code>;</code>
<code> </code><code>//使用資料輸出流對象的方法寫出資料到輸出流</code>
<code> </code><code>dos.write(a);</code>
<code> </code><code>dos.write(b);</code>
<code> </code><code>dos.write(c);</code>
<code> </code><code>//關閉資料輸出流</code>
<code> </code><code>dos.close();</code>
<code> </code><code>//建立資料輸入流</code>
<code> </code><code>datainputstream dis = </code><code>new</code> <code>datainputstream(</code>
<code> </code><code>new</code> <code>bufferedinputstream(</code><code>new</code> <code>fileinputstream(</code><code>"d:/itzhai/arthinking.txt"</code><code>)));</code>
<code> </code><code>//使用資料輸入流的方法從輸入流中讀取資料</code>
<code> </code><code>system.out.println(dis.readbyte() + dis.readchar() + dis.readint());</code>
<code> </code><code>//關閉資料輸入流</code>
<code> </code><code>dis.close();</code>
使用datainputstream和dataoutputstream資料檔案流的一般步驟:
建立位元組檔案流對象
基于位元組檔案流對象建立資料檔案流對象
用資料檔案流對象的方法對基本類型的資料進行輸入/輸出