摘要:從應(yīng)用流向目的地稱為輸出流,從目的地流向應(yīng)用稱為輸入流。裝飾器模式裝飾器模式允許向一個(gè)現(xiàn)有的對象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。以及家屬對于裝飾器模式的體現(xiàn),也以此類推。
流概述
Java中,流是一種有序的字節(jié)序列,可以有任意的長度。從應(yīng)用流向目的地稱為輸出流,從目的地流向應(yīng)用稱為輸入流。
Java的流族譜Java的java.io包中囊括了整個(gè)流的家族,輸出流和輸入流的譜系如下所示:
InputStream和OutputStream分別是輸入輸出流的頂級抽象父類,只定義了一些抽象方法供子類實(shí)現(xiàn)。
在輸出流OutputStream中,如果你需要向一個(gè)輸出流寫入數(shù)據(jù),可以調(diào)用void write(int b)方法,這個(gè)方法會(huì)將b的低八位寫入流中,高24位將會(huì)被自動(dòng)忽略。如果想要批量寫入數(shù)據(jù)呢,那么可以調(diào)用void write(byte[] b) 方法將一個(gè)字節(jié)數(shù)組的內(nèi)容全部寫入流中,同時(shí)還有void write(byte[] b, int off, int len)可以讓你指定從哪里寫入多少數(shù)據(jù)。
如果你希望你向流中寫入的數(shù)據(jù)能夠盡快地輸送到目的地,比如說文件,那么可以在寫入數(shù)據(jù)后,調(diào)用flush()方法將當(dāng)前輸出流刷到操作系統(tǒng)層面的緩沖區(qū)中。不過需要注意的是,此方法并不保證數(shù)據(jù)立馬就能刷到實(shí)際的物理目的地(比如說存儲(chǔ))。
使用完流后應(yīng)該調(diào)用其close()方法將流關(guān)閉,流關(guān)閉時(shí),將會(huì)先flush,后關(guān)閉。
在輸入流InputStream中,可以通過int read() 方法來從流中讀取一個(gè)字節(jié),批量讀取字節(jié)可以通過int read(byte[] b)或者int read(byte[] b, int off, int len)來實(shí)現(xiàn),這兩個(gè)方法的返回值為實(shí)際讀取到的字節(jié)數(shù)。如果需要重復(fù)讀取流中某段數(shù)據(jù),可以在讀取之前先使用void mark(int readlimit)方法在當(dāng)前位置做一個(gè)記號(hào),之后通過void reset()方法返回到之前做標(biāo)記的位置,不過在做這些標(biāo)記操作之前,需要先通過boolean markSupported()方法來確定該流是否支持標(biāo)記。如果對某些可預(yù)知的數(shù)據(jù)不感興趣,可以使用long skip(long n)來調(diào)過一些流中的一些數(shù)據(jù)。
使用完流,無論是輸入還是輸出流,都要調(diào)用其close()方法對其進(jìn)行關(guān)閉。
裝飾器模式裝飾器模式(Decorator Pattern)允許向一個(gè)現(xiàn)有的對象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類的一個(gè)包裝。
這種設(shè)計(jì)模式創(chuàng)建了一個(gè)裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。
以InputStream為例,它是一個(gè)抽象類:
public abstract class InputStream implements Closeable { ... ... }
并定義有抽象方法
public abstract int read() throws IOException;
該抽象方法由具體的子類去實(shí)現(xiàn),通過InputStream的族譜圖可以看到,直接繼承了InputStream,并且提供某一特定功能的子類有:
ByteArrayInputStream
FileInputStream
ObjectInputStream
PipedInputStream
SequenceInputStream
StringBufferInputStream
這些子類都具有特定的功能,比如說,F(xiàn)ileInputStream代表一個(gè)文件輸入流并提供讀取文件內(nèi)容的功能,ObjectInputStream提供了對象反序列化的功能。
InputStream這個(gè)抽象類有一個(gè)子類與上述其它子類非常不同,這個(gè)子類就是FilterInputStream,可參見上圖中的InputStream族譜圖。
翻開FilterInputStream的代碼,我們可以看到,它內(nèi)部又維護(hù)了一個(gè)InputStream的成員對象,并且它的所有方法,都是調(diào)用這個(gè)成員對象的同名方法。
換句話說,F(xiàn)ilterInputStream它什么事都不做。就是把調(diào)用委托給內(nèi)部的InputStream成員對象。如下所示:
public class FilterInputStream extends InputStream { protected volatile InputStream in; protected FilterInputStream(InputStream in) { this.in = in; } public int read() throws IOException { return in.read(); } public int read(byte b[]) throws IOException { return read(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); } public long skip(long n) throws IOException { return in.skip(n); } public int available() throws IOException { return in.available(); } public void close() throws IOException { in.close(); } public synchronized void mark(int readlimit) { in.mark(readlimit); } public synchronized void reset() throws IOException { in.reset(); } public boolean markSupported() { return in.markSupported(); }
FilterInputStream的又有其子類,分別是:
BufferedInputStream
DataInputStream
LineNumberInputStream
PushbackInputStream
雖然從上面代碼看FilterInputStream并沒有做什么有卵用的事,但是它的子類可不同了,以BufferedInputStream為例,這個(gè)類提供了提前讀取數(shù)據(jù)的功能,也就是緩沖的功能。可以看看它的read方法:
public synchronized int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) return -1; } return getBufIfOpen()[pos++] & 0xff; }
可以看到,當(dāng)pos>=count時(shí),意即需要提前緩沖一些數(shù)據(jù)的時(shí)候到了,那么就會(huì)調(diào)用fill()將緩沖區(qū)加滿,以便后續(xù)讀取。由于本文只討論io流的裝飾器模式,所以關(guān)于具體實(shí)現(xiàn)細(xì)節(jié)將不會(huì)展開討論,比如本文不會(huì)討論fill()方法是如何實(shí)現(xiàn)的,在這里可以先將它當(dāng)做一個(gè)黑盒子。
從這里可以開始感受到,BufferedInputStream就是一個(gè)裝飾者,它能為一個(gè)原本沒有緩沖功能的InputStream添加上緩沖的功能。
比如我們常用的FileInputStream,它并沒有緩沖功能,我們每次調(diào)用read,都會(huì)向操作系統(tǒng)發(fā)起調(diào)用索要數(shù)據(jù)。假如我們通過BufferedInputStream來裝飾它,那么每次調(diào)用read,會(huì)預(yù)先向操作系統(tǒng)多拿一些數(shù)據(jù),這樣就不知不覺中提高了程序的性能。如以下代碼所示:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("/home/user/abc.txt")));
同理,對于其它的FilterInputStream的子類,其作用也是一樣的,那就是裝飾一個(gè)InputStream,為它添加它原本不具有的功能。OutputStream以及家屬對于裝飾器模式的體現(xiàn),也以此類推。
JDK中的io流的設(shè)計(jì)是設(shè)計(jì)模式中裝飾器模式的一個(gè)經(jīng)典示范,如果細(xì)心發(fā)現(xiàn),JDK中還有許多其它設(shè)計(jì)模式的體現(xiàn),比如說監(jiān)聽者模式等等。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65366.html
摘要:分類一按操作方式類結(jié)構(gòu)字節(jié)流和字符流字節(jié)流以字節(jié)為單位,每次次讀入或讀出是位數(shù)據(jù)。該對象并不是流體系中的一員,其封裝了字節(jié)流,同時(shí)還封裝了一個(gè)緩沖區(qū)字符數(shù)組,通過內(nèi)部的指針來操作字符數(shù)組中的數(shù)據(jù)。 分類一:按操作方式(類結(jié)構(gòu)) 字節(jié)流和字符流: 字節(jié)流:以字節(jié)為單位,每次次讀入或讀出是8位數(shù)據(jù)。可以讀任何類型數(shù)據(jù)。 字符流:以字符為單位,每次次讀入或讀出是16位數(shù)據(jù)。其只能讀取字符類...
摘要:在包下主要包括輸入輸出兩種流,每種輸入輸出流又可分為字節(jié)流和字符流兩大類。輸入輸出是從程序運(yùn)行所在的內(nèi)存的角度而言的。的輸入流主要由和作為基類,而輸出流主要由和作為基類。 本章主要參考和摘自瘋狂java講義上面的(java編程思想的后面看過后有新的內(nèi)容再補(bǔ)充進(jìn)去吧)。 輸入輸出是所有程序都必需的部分————使用輸入機(jī)制允許程序讀取外部數(shù)據(jù)(包括磁盤、光盤等存儲(chǔ)設(shè)備上的數(shù)據(jù)和用戶輸入的...
摘要:流分類由此可見,流很龐大從不同角度進(jìn)行分類數(shù)據(jù)分類按處理數(shù)據(jù)單位分為字節(jié)流和字符流。處理數(shù)據(jù)是音頻視頻文本等一切為字節(jié)流,僅能處理文本的為字符流。功能分類節(jié)點(diǎn)流和處理流。從向一個(gè)特定的設(shè)備磁盤網(wǎng)絡(luò)等讀寫數(shù)據(jù)的流稱為節(jié)點(diǎn)流,也常被稱為低級流。 嗨嘍,小樂又來了,今天要給大家送上的技術(shù)文章是Java重點(diǎn)知識(shí)-IO流。 先來看看IO流的思維導(dǎo)圖吧。showImg(https://segmen...
摘要:本文只是尋找設(shè)計(jì)模式在中的應(yīng)用。來補(bǔ)全這一塊工廠模式中的應(yīng)用包線程池解釋和代碼線程池中有線程創(chuàng)建工廠。狀態(tài)模式中的應(yīng)用解釋和代碼根據(jù)一個(gè)指針的狀態(tài)而改變自己的行為適配器模式中的應(yīng)用解釋和代碼將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。 前言 最近重學(xué)設(shè)計(jì)模式,而且還有很多源碼要看。所以就想一舉兩得。從源碼中尋找設(shè)計(jì)模式。順便還可以看看源碼。。。本文只是尋找設(shè)計(jì)模式在java中的應(yīng)用。優(yōu)...
摘要:采用通信模型的服務(wù)端通常由一個(gè)獨(dú)立的線程負(fù)責(zé)監(jiān)聽客戶端的連接它接收到客戶端連接請求之后為每個(gè)客戶端創(chuàng)建一個(gè)新的線程進(jìn)行鏈路處理處理完成之后通過輸出流返回應(yīng)答給客戶端線程銷毀這就是典型的一請求一應(yīng)答通信模型該模型最大的問題就是缺乏彈性伸縮能力 BIO 采用 BIO 通信模型的服務(wù)端, 通常由一個(gè)獨(dú)立的 Acceptor 線程負(fù)責(zé)監(jiān)聽客戶端的連接, 它接收到客戶端連接請求之后為每個(gè)客戶端創(chuàng)...
閱讀 2463·2021-11-11 16:54
閱讀 1244·2021-09-22 15:23
閱讀 3701·2021-09-07 09:59
閱讀 2039·2021-09-02 15:41
閱讀 3315·2021-08-17 10:13
閱讀 3095·2019-08-30 15:53
閱讀 1270·2019-08-30 13:57
閱讀 1240·2019-08-29 15:16