Java IO 之 SequenceInputStream 原理解析
概述
今天給大家分享一個(gè)比較有意思的 IO 流。SequenceInputStream ,聽(tīng)名字顧名思義。
SequenceInputStream 流可以把多個(gè) InputStream 合并為一個(gè) InputStream . 按照指定的順序,把幾個(gè)輸入流連續(xù)地合并起來(lái),使用起來(lái)像一個(gè)流一樣。并且使它們像單個(gè)輸入流一樣出現(xiàn)。每個(gè)輸入流依次被讀取,直到到達(dá)該流的末尾。然后“序列輸入流”類關(guān)閉這個(gè)流并自動(dòng)地切換到下一個(gè)輸入流。
合并流的作用是將多個(gè)源合并合一個(gè)源。
使用場(chǎng)景
比如現(xiàn)在有三個(gè)文件【1.txt】、【2.txt】、【3.txt】;現(xiàn)在要把這三個(gè)文件按照1、2、3的順序合并成一個(gè)文件輸出到 【all.txt】文件中。
如果不知道有這個(gè)流,大家可能都是自己一個(gè)一個(gè)文件的去讀,自己合并到一個(gè)文件中。
有了這個(gè)流,我們操作起來(lái),代碼更加優(yōu)雅。
示例
public class SequenceInputStreamDemo {public static void sequenceStream() {// 創(chuàng)建字節(jié)輸入流對(duì)象s1,s2,s3try (InputStream s1 = new FileInputStream(new File("d:\\1.txt"));InputStream s2 = new FileInputStream(new File("d:\\2.txt"));InputStream s3 = new FileInputStream(new File("d:\\3.txt"));) {/*** SequenceInputStream(Enumeration<? extends InputStream> e)* 通過(guò)記住參數(shù)來(lái)初始化新創(chuàng)建的 SequenceInputStream, 該參數(shù)必須是生成運(yùn)行時(shí)類型為 InputStream* 對(duì)象的 Enumeration 型參數(shù)。*/// 創(chuàng)建一個(gè)Vector類對(duì)象vVector<InputStream> v = new Vector<>();/*** void addElement(E obj) 將指定的組件添加到此向量的末尾,將其大小增加 1。*/// 將3個(gè)字節(jié)流對(duì)象添加到Vector容器中v.addElement(s1);v.addElement(s2);v.addElement(s3);// 獲取Vector對(duì)象中的元素Enumeration<InputStream> e = v.elements();// 將Enumeration對(duì)象中的流合并(創(chuàng)建一個(gè)序列流,用于合并多個(gè)字節(jié)流文件s1,s2,s3)try (SequenceInputStream se = new SequenceInputStream(e);OutputStream os = new FileOutputStream("d:\\all.txt")) {byte[] b = new byte[1024];int len = 0;while ((len = se.read(b)) != -1) {os.write(b, 0, len);os.write("\r\n".getBytes());}System.out.println("合并成功");} catch (IOException ex) {ex.printStackTrace();}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {sequenceStream();} }該示例是,把D盤目錄下的三個(gè)文件【1.txt】、【2.txt】、【3.txt】使用SequenceInputStream 流,按照 指定的文件的順序合并輸出到 【all.txt】 文件中。
SequenceInputStream 源碼解析
public class SequenceInputStream extends InputStream {Enumeration<? extends InputStream> e;InputStream in;...... }SequenceInputStream 繼承 InputStream。
定義了一個(gè) Enumeration 的一個(gè)變量。該變量存儲(chǔ)的是所有需要合并的InputStream。
定義了一個(gè) InputStream的一個(gè)變量。該變量是記錄 Enumeration 中正在讀去的 InputStream。
Enumeration
Enumeration 接口是Iterator迭代器的“古老版本”,從JDK 1.0開(kāi)始,Enumeration接口就已經(jīng)存在了(Iterator從JDK 1.2才出現(xiàn))。Enumeration接口只有兩個(gè)方法。
構(gòu)造方法
提供兩個(gè)構(gòu)造方法。
* 1、提供 Enumeration 類型的參數(shù)。
把傳過(guò)來(lái)的參數(shù)賦值給 e 變量。
并調(diào)用 nextStream() 方法。
現(xiàn)在的迭代器都在使用Iterator,而這里為啥還在使用Enumeration 呢?
因?yàn)?Iterator 是在JDK1.2以后才有的,而SequenceInputStream 這個(gè)流在JDK1.0就已經(jīng)存在了,故使用 Enumeration 當(dāng)參數(shù)。
- 2、提供兩個(gè) InputStream 類型的參數(shù)。
構(gòu)造中把這兩個(gè)流添加到 Vector 數(shù)組中,然后調(diào)用 elements 方法放回一個(gè) Enumeration 類型,并賦值給 e 變量。
并調(diào)用 nextStream() 方法。
nextStream 方法
1、判斷該流是否不為null,不為null 則把當(dāng)前 InputStream 關(guān)閉。
2、該方法是先判斷 Enumeration 中是否有可用的元素,如果獲取 Enumeration 迭代器中下一個(gè)的元素,并賦值給 in 變量。
read 方法
讀取 InputStream 中的數(shù)據(jù)。如果當(dāng)前 InputStream 讀取完了,再調(diào)用 nextStream 方法,獲取下一個(gè)流,然后繼續(xù)讀取。直到所有的流都已經(jīng)讀取完畢。
close 方法
close 方法會(huì)關(guān)閉剩下沒(méi)有讀取完的所有的 InputStream。
讀取過(guò)的InputStream 會(huì)在 調(diào)用 nextStream 方法中關(guān)閉。所以在這只需要關(guān)閉沒(méi)有讀取完的流就可以了。
看完源碼是不是感覺(jué) SequenceInputStream 超級(jí)簡(jiǎn)單,自己也可以實(shí)現(xiàn)一個(gè)。
想了解更多精彩內(nèi)容請(qǐng)關(guān)注我的公眾號(hào)
本人簡(jiǎn)書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
點(diǎn)擊這里快速進(jìn)入簡(jiǎn)書
GIT地址:http://git.oschina.net/brucekankan/
點(diǎn)擊這里快速進(jìn)入GIT
總結(jié)
以上是生活随笔為你收集整理的Java IO 之 SequenceInputStream 原理解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java 序列化 原理解析
- 下一篇: Java IO 之 管道流 原理分析