成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java IO : 流,以及裝飾器模式在其上的運(yùn)用

fuyi501 / 766人閱讀

摘要:從應(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

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

相關(guān)文章

  • Java IO

    摘要:分類一按操作方式類結(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ù)。其只能讀取字符類...

    Salamander 評論0 收藏0
  • 第十五章 輸入輸出系統(tǒng)

    摘要:在包下主要包括輸入輸出兩種流,每種輸入輸出流又可分為字節(jié)流和字符流兩大類。輸入輸出是從程序運(yùn)行所在的內(nèi)存的角度而言的。的輸入流主要由和作為基類,而輸出流主要由和作為基類。 本章主要參考和摘自瘋狂java講義上面的(java編程思想的后面看過后有新的內(nèi)容再補(bǔ)充進(jìn)去吧)。  輸入輸出是所有程序都必需的部分————使用輸入機(jī)制允許程序讀取外部數(shù)據(jù)(包括磁盤、光盤等存儲(chǔ)設(shè)備上的數(shù)據(jù)和用戶輸入的...

    hankkin 評論0 收藏0
  • 樂字節(jié)Java之file、IO基礎(chǔ)知識(shí)和操作步驟

    摘要:流分類由此可見,流很龐大從不同角度進(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...

    pkhope 評論0 收藏0
  • 設(shè)計(jì)模式在jdk中的應(yīng)用

    摘要:本文只是尋找設(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)...

    dingding199389 評論0 收藏0
  • BIO、偽異步 IO、AIO和NIO

    摘要:采用通信模型的服務(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)...

    ideaa 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<