欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java基礎(chǔ):流Stream詳解

 更新時(shí)間:2021年09月17日 14:28:32   作者:CodingALife  
Stream流是數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(集合、數(shù)組等)所生成的元素序列。這篇文章主要介紹了Java8新特性Stream流的相關(guān)資料,需要的朋友參考下吧

寫在前面

從Java 1.0開始,引入java.io包;到Java 1.4再擴(kuò)展了java.nio包;再到j(luò)ava 1.7又添加了新的流類,使得Java的流機(jī)制變得十分強(qiáng)大。

一、"流"概念

James Gosling所著《Java程序設(shè)計(jì)》中描述Java I/O流模式圖如下。Program是中間環(huán)節(jié),用于對(duì)Source進(jìn)行處理,然后輸出到Dest處。

b654b83fa3312585d665d043388b518d.png

Java中的"流"就是指把數(shù)據(jù)從一個(gè)對(duì)象移動(dòng)到另一個(gè)對(duì)象的流動(dòng)模式的抽象。其實(shí)Java的流模式用水流或者電流模型來解釋是很容易理解的。

363cc7573ed96e3ea734d47025759159.png

James Gosling的Java流模式圖與水流模式圖概念映射。數(shù)據(jù)源(data source)即水庫,數(shù)據(jù)目的地(data destination)就是臉盆,數(shù)據(jù)(data)就是水,流(stream)實(shí)例化就是在管子中流動(dòng)的水流。

輸入流(input stream)就是用水泵從水庫中抽出來要到水管中的水,輸出流(output stream)經(jīng)過水龍頭將要達(dá)到臉盆中的水,計(jì)算機(jī)內(nèi)存(memory)就是上圖中的水流管道,關(guān)閉輸入流(close input stream)就是關(guān)閉水泵開關(guān),關(guān)閉輸出流(close output stream)就是關(guān)閉關(guān)閉水龍頭開關(guān)。

更進(jìn)一步說,具體的水庫和臉盆分別對(duì)應(yīng)于Java中輸入流對(duì)象和輸出流對(duì)象。水流可以分成一粒一粒的水分子,這些水分子映射成計(jì)算機(jī)二進(jìn)制位(bit)0/1,其組成的水滴映射成計(jì)算機(jī)字節(jié)流(字節(jié)是計(jì)算機(jī)儲(chǔ)存信息的基本單位)。字節(jié)流和字符流在物理層面的實(shí)現(xiàn)都是比特流,二進(jìn)制數(shù)據(jù)流可以認(rèn)為是字節(jié)流,而字符流是遵循unicode編碼規(guī)則的字節(jié)流。因此計(jì)算機(jī)中的"流"概念實(shí)際上就是指字節(jié)數(shù)據(jù)(bytes data)從源對(duì)象對(duì)按順序流向目標(biāo)對(duì)象的一種流動(dòng)形式。

e31533f5a5cfd51c65279543be6e302a.png

二、流的分類

1、按流的方向分為:輸入流、輸出流

判斷當(dāng)前流是輸入流還是輸出流的依據(jù)是二進(jìn)制數(shù)據(jù)相對(duì)于計(jì)算機(jī)內(nèi)存的位置,輸入流是輸入計(jì)算機(jī)內(nèi)存是二進(jìn)制數(shù)據(jù),輸出流是從計(jì)算機(jī)內(nèi)存輸出的二進(jìn)制數(shù)據(jù)。而計(jì)算機(jī)程序在運(yùn)行期間會(huì)儲(chǔ)存在到計(jì)算機(jī)內(nèi)存中,因此總的來說就是數(shù)據(jù)的來源、取向是相對(duì)程序而言的。比如鍵盤鍵入數(shù)據(jù)屬于輸入流,內(nèi)存數(shù)據(jù)持久化到磁盤中屬于輸出流。

cd73d9ac40fe5f303e72def8f682ddf4.png

說明:本圖片取自互聯(lián)網(wǎng),糾正補(bǔ)充為流的來源有網(wǎng)絡(luò)連接、內(nèi)存塊、磁盤(文件)、鍵盤等;流的去向也基本是這些。

2、按流處理數(shù)據(jù)的單位分為:字節(jié)流、字符流

從物理層面來看,流中數(shù)據(jù)都是二進(jìn)制比特流。而計(jì)算機(jī)中儲(chǔ)存信息的基本單位是字節(jié)(Byte)。因此,可以認(rèn)為計(jì)算機(jī)中信息傳輸在底層是靠字節(jié)流來實(shí)現(xiàn)的。字符流只是通過不同的字符編碼方式,對(duì)字節(jié)流的封裝,即字符流的實(shí)現(xiàn)還是得依靠字節(jié)流。

3、按流的功能分為:節(jié)點(diǎn)流(又稱低級(jí)流)、過濾流(又稱高級(jí)流、處理流、包裝流)

節(jié)點(diǎn)流(Node Stream)是流管道兩端直接連接data source和data destination上的,即為取放數(shù)據(jù)的真實(shí)載體,在流通道本身不對(duì)數(shù)據(jù)做任何加工,因而也被稱為低級(jí)流。

節(jié)點(diǎn)流從一個(gè)特定的數(shù)據(jù)源讀寫數(shù)據(jù)。即節(jié)點(diǎn)流是直接操作文件,網(wǎng)絡(luò)等的流,例如FileInputStream和FileOutputStream,他們直接從文件中讀取或往文件中寫入字節(jié)流。

2374f1b0340903f7b84a7a89c3f94422.png

“連接”在已存在的流(節(jié)點(diǎn)流或處理流)之上通過對(duì)數(shù)據(jù)的處理為程序提供更為強(qiáng)大的讀寫功能。過濾流是使用一個(gè)已經(jīng)存在的輸入流或輸出流連接創(chuàng)建的,過濾流就是對(duì)節(jié)點(diǎn)流進(jìn)行一系列的包裝。例如BufferedInputStream和BufferedOutputStream,使用已經(jīng)存在的節(jié)點(diǎn)流來構(gòu)造,提供帶緩沖的讀寫,提高了讀寫的效率,以及DataInputStream和DataOutputStream,使用已經(jīng)存在的節(jié)點(diǎn)流來構(gòu)造,提供了讀寫Java中的基本數(shù)據(jù)類型的功能。他們都屬于過濾流。

f71da4ab9fa8bc1a96224fc34c9d1ad0.png

public static void main(String[] args) throws IOException {
        // 節(jié)點(diǎn)流FileOutputStream直接以A.txt作為數(shù)據(jù)源操作
        FileOutputStream fileOutputStream = new FileOutputStream("A.txt");
        // 過濾流BufferedOutputStream進(jìn)一步裝飾節(jié)點(diǎn)流,提供緩沖寫
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
                fileOutputStream);
        // 過濾流DataOutputStream進(jìn)一步裝飾過濾流,使其提供基本數(shù)據(jù)類型的寫
        DataOutputStream out = new DataOutputStream(bufferedOutputStream);
        out.writeInt(3);
        out.writeBoolean(true);
        out.flush();
        out.close();
        // 此處輸入節(jié)點(diǎn)流,過濾流正好跟上邊輸出對(duì)應(yīng),讀者可舉一反三
        DataInputStream in = new DataInputStream(new BufferedInputStream(
                new FileInputStream("A.txt")));
        System.out.println(in.readInt());
        System.out.println(in.readBoolean());
        in.close();
}

理解:

  • FileOutputStream是根據(jù)二進(jìn)制010101一個(gè)一個(gè)字節(jié)處理
  • BufferedOutputStream是對(duì)字節(jié)封裝成buffered,以緩沖區(qū)處理
  • DataOutputStream是以字符串形式,類似(“hello”)處理。

4、字節(jié)流與字符流區(qū)別

  • 字節(jié)流默認(rèn)是不帶緩沖區(qū)的,而字符流默認(rèn)是帶緩沖區(qū)的。
  • 字節(jié)流是底層數(shù)據(jù)流,是數(shù)據(jù)有意義的最小單位。字符流是字節(jié)流的包裝,底層實(shí)現(xiàn)是字節(jié)流。
  • 字節(jié)流讀取的時(shí)候,讀到一個(gè)字節(jié)就返回一個(gè)字節(jié);字符流使用了字節(jié)流讀到一個(gè)或多個(gè)字節(jié)(中文對(duì)應(yīng)的字節(jié)數(shù)是兩個(gè),在UTF-8碼表中是3個(gè)字節(jié))時(shí)。先去查指定的編碼表,將查到的字符返回。
  • 字節(jié)流可以處理所有類型數(shù)據(jù),如:圖片,MP3,AVI視頻文件,而字符流只能處理字符數(shù)據(jù)。只要是處理純文本數(shù)據(jù),就要優(yōu)先考慮使用字符流,除此之外都用字節(jié)流。文本文件可以用字節(jié)流來實(shí)現(xiàn),當(dāng)然使用字符流速度會(huì)更快。

三、流的方法

1、字節(jié)流

字節(jié)輸入流類:FileInputStream、BufferedInputStream和DataInputStream

FileInputStream:此類用于從本地文件系統(tǒng)中讀取文件內(nèi)容。

構(gòu)造方法:

  • FileInputStream(File file):打開一個(gè)到實(shí)際文件的連接來創(chuàng)建一個(gè)FileInputStream,該文件通過文件系統(tǒng)中的File對(duì)象file指定。
  • FileInputStream(String name):打開一個(gè)到實(shí)際文件的連接來創(chuàng)建一個(gè)FileInputStream,該文件通過文件系統(tǒng)中的路徑名name指定。

常用方法:

  • int available():返回下一次對(duì)此輸入流調(diào)用的方法不受阻塞地從此輸入流讀?。ɑ蛱^)的估計(jì)剩余字節(jié)數(shù)。
  • void close():關(guān)閉此文件輸入流并釋放與該流關(guān)聯(lián)的所有系統(tǒng)資源。

BufferedInputStream此類本身帶有一個(gè)緩沖區(qū),在讀取數(shù)據(jù)時(shí),先放到緩沖區(qū)中,可以減少對(duì)數(shù)據(jù)源的訪問,提高運(yùn)行的效率。

構(gòu)造方法:

  • BufferedInputStream(InputStream in):創(chuàng)建一個(gè)BufferedInputStream并保存其參數(shù),即輸入流in,以便將來使用。
  • BufferedInputStream(InputStream in,int size):創(chuàng)建一個(gè)具有指定緩沖區(qū)大小的BufferedInputStream并保存其參數(shù),即輸入流in,以便將來使用。

常用方法:

  • int available():返回下一次對(duì)此輸入流調(diào)用的方法不受阻塞地從此輸入流讀?。ɑ蛱^)的估計(jì)剩余字節(jié)數(shù)。
  • void close():關(guān)閉此輸入流并釋放與該流關(guān)聯(lián)的所有系統(tǒng)資源。
  • int read():從輸入流中讀取數(shù)據(jù)的下一個(gè)字節(jié)。
  • int read(byte[] b,int off,int len):從此字節(jié)輸入流中給定偏移量處開始將各字節(jié)讀取到指定的byte數(shù)組中。

DataInputStream:該類提供一些基于多字節(jié)讀取方法,從而可以讀取基本數(shù)據(jù)類型的數(shù)據(jù)。

構(gòu)造方法:

  • DataInputStream(InputStream in):使用指定的底層InputStream創(chuàng)建一個(gè)DataInputStream。

常用方法:

  • int read(byte[] b):從包含的輸入流中讀取一定數(shù)量的字節(jié),并將它們存儲(chǔ)到緩沖區(qū)數(shù)組b中。
  • int read(byte[] b,int off,int len):從包含的輸入流中將最多l(xiāng)en個(gè)字節(jié)讀入一個(gè)byte數(shù)組中。

字節(jié)輸出流類:FileOutputStream、BufferedOutputStream和DataOutputStream

FileOutputStream:此類用于從本地文件系統(tǒng)的文件中寫入數(shù)據(jù)。

構(gòu)造方法:

  • FileOutputStream(File file):創(chuàng)建一個(gè)向指定File對(duì)象表示的文件中寫入數(shù)據(jù)的文件輸出流。FileOutputStream(String name):創(chuàng)建一個(gè)向具有指定名稱的文件中寫入數(shù)據(jù)的輸出文件流。

常用方法:

  • void close():關(guān)閉此文件輸出流并釋放與此流有關(guān)的所有系統(tǒng)資源。
  • FileDescriptor getFD():返回與此流有關(guān)的文件描述符。
  • void write(byte[] b):將b.length個(gè)字節(jié)從指定byte數(shù)組寫入此文件輸出流中。
  • void write(byte[] b,int off,int len):將指定byte數(shù)組中從偏移量off開始的len個(gè)字節(jié)寫入此文件輸出流。
  • void write(int b):將指定字節(jié)寫入此文件輸出流。

BufferedOutputStream:此類本身帶有一個(gè)緩沖區(qū),在寫入數(shù)據(jù)時(shí),先放到緩沖區(qū)中,實(shí)現(xiàn)緩沖的數(shù)據(jù)流。

構(gòu)造方法:

  • BufferedOutputStream(OutputStream out):創(chuàng)建一個(gè)新的緩沖輸出流,來將數(shù)據(jù)寫入指定的底層輸入流。
  • BufferedOutputStream(OutputStream out,int size):創(chuàng)建一個(gè)新的緩沖輸出流,來將具有指定緩沖區(qū)大小的數(shù)據(jù)寫入指定的底層輸出流。

常用方法:

  • void flush():刷新此緩沖的輸出流。
  • void write(byte[] b,int off,int len):將指定byte數(shù)組中從偏移量off開始的len個(gè)字節(jié)寫入此緩沖的輸出流。
  • void write(int b):將指定的字節(jié)寫入此緩沖的輸出流。

DataOutputStream(OutputStream out):創(chuàng)建一個(gè)新的數(shù)據(jù)輸出流,將數(shù)據(jù)寫入指定基礎(chǔ)輸出流。

常用方法:

  • void flush():清空此數(shù)據(jù)輸出流。
  • int size():返回計(jì)數(shù)器written的當(dāng)前值,即到目前為止寫入此數(shù)據(jù)輸出流的字節(jié)數(shù)。
  • void write(byte[] b,int off,int len):將指定byte數(shù)組中從偏移量off開始的len個(gè)字節(jié)寫入基礎(chǔ)輸出流。
  • void write(int b):將指定字節(jié)(參數(shù)b的八個(gè)低位)寫入基礎(chǔ)輸出流。

2、字符流

FileReader:用來讀取字符文件的便捷類。此類的構(gòu)造方法假定默認(rèn)字符編碼和默認(rèn)字節(jié)緩沖區(qū)大小都是適當(dāng)?shù)?/p>

構(gòu)造方法:

FileReader(File file):在給定從中讀取數(shù)據(jù)的File的情況下創(chuàng)建一個(gè)新的FileReader。FileReader(String fileName):在給定從中讀取數(shù)據(jù)的文件名的情況下創(chuàng)建一個(gè)新的FileReader。

BufferedReader類是Reader類的子類,為Reader對(duì)象添加字符緩沖器,為數(shù)據(jù)輸入分配內(nèi)存存儲(chǔ)空間,存取數(shù)據(jù)更為有效。

構(gòu)造方法:

  • BufferedReader(Reader in):創(chuàng)建一個(gè)使用默認(rèn)大小輸入緩沖區(qū)的緩沖字符輸入流。
  • BufferedReader(Reader in,int sz):創(chuàng)建一個(gè)使用指定大小輸入緩沖區(qū)的緩沖字符輸入流。

操作方法:

  • void close():關(guān)閉該流并釋放與之關(guān)聯(lián)的所有資源。
  • void mark(int readAheadLimit):標(biāo)記流中的當(dāng)前為止。
  • boolean markSupported();判斷此流是否支持mark()操作。
  • int read():讀取單個(gè)字符。
  • int read(char[] cbuf,int off,int len):將字符讀入數(shù)組的某一部分。
  • String readLine():讀取一個(gè)文本行。
  • boolean ready():判斷此流是否已準(zhǔn)備好被讀取。
  • void reset():將流重置到最新的標(biāo)記。
  • long skip(long n):跳過字符。

FileWriter:用來寫入字符文件的便捷類,可用于寫入字符流。

構(gòu)造方法:

FileWriter(File file):根據(jù)給定的File對(duì)象構(gòu)造一個(gè)FileWriter對(duì)象。

FileWriter(String filename):根據(jù)給定的文件名構(gòu)造一個(gè)FileWriter對(duì)象。

BufferedWriter: 將文本寫入字符輸出流,緩沖各個(gè)字符,從而提供單個(gè)字符、數(shù)組和字符串的高效寫入。

緩沖流的目的:

操作流的時(shí)候,習(xí)慣定義一個(gè)byte/char數(shù)組。

int read(): 每次都從磁盤文件中讀取一個(gè)字節(jié)。 直接操作磁盤文件性能極低。

解決方案:定義一個(gè)數(shù)組作為緩沖區(qū)。

byte[] buffer = new byte[1024];該數(shù)組其實(shí)就是一個(gè)緩沖區(qū)。

一次性從磁盤文件中讀取1024個(gè)字節(jié)。如此以來,操作磁盤文件的次數(shù)少了,性能得以提升。提供的默認(rèn)緩存區(qū)大小是8192(1024*8),我們一般不用修改大小

public class BufferStreamDemo {
    public static void main(String[] args) throws Exception {
        File file = new File("file/aaa.txt");
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        out.write("中國".getBytes());
        out.close();
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
        byte[] buffer = new byte[1024];
        int len = -1;
        while((len = in.read(buffer)) != -1){
            System.out.println(new String(buffer, 0, len));
        }
        in.close();
    }
}
public class BufferCharacterDemo {
    public static void main(String[] args) throws Exception {
        File file = new File("file/aaa.txt");
        BufferedWriter in = new BufferedWriter(new FileWriter(file,true));
        in.newLine();//用來換行等同于‘\n'
        in.write("美國");
        in.newLine();
        in.write("馬來西亞");
        in.close();
        BufferedReader out = new BufferedReader(new FileReader(file));
        String line = null;
        //按行讀取
        while((line = out.readLine()) != null){
            System.out.println(line);
        }
        out.close();
    }
}

4、流相關(guān)設(shè)計(jì)模式

處理流/包裝流(相對(duì)于節(jié)點(diǎn)流更高級(jí)) 裝飾設(shè)計(jì)模式/包裝模式:

  • 隱藏了底層的節(jié)點(diǎn)流的差異,并對(duì)外提供了更方便的輸入/輸出功能,讓我們只關(guān)心高級(jí)流的操作.
  • 使用處理流包裝了節(jié)點(diǎn)流,程序直接操作處理流,讓節(jié)點(diǎn)流與底層的設(shè)備做IO操作.
  • 只需要關(guān)閉處理流即可.

參考:https://blog.csdn.net/dreamzuora/article/details/79691702

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • mybatis執(zhí)行批量更新batch update 的方法(oracle,mysql兩種)

    mybatis執(zhí)行批量更新batch update 的方法(oracle,mysql兩種)

    這篇文章主要介紹了mybatis執(zhí)行批量更新batch update 的方法,提供oracle和mysql兩種方法,非常不錯(cuò),需要的朋友參考下
    2017-01-01
  • 關(guān)于mybatis if else if 條件判斷SQL片段表達(dá)式取值和拼接問題

    關(guān)于mybatis if else if 條件判斷SQL片段表達(dá)式取值和拼接問題

    這篇文章主要介紹了mybatis if else if 條件判斷SQL片段表達(dá)式取值和拼接,文章通過自己真實(shí)使用的例子給大家詳細(xì)介紹,需要的朋友可以參考下
    2021-09-09
  • Spring?Data?Elasticsearch?5.x實(shí)現(xiàn)單詞糾錯(cuò)和自動(dòng)補(bǔ)全

    Spring?Data?Elasticsearch?5.x實(shí)現(xiàn)單詞糾錯(cuò)和自動(dòng)補(bǔ)全

    這篇文章主要為大家介紹了Spring?Data?Elasticsearch?5.x實(shí)現(xiàn)單詞糾錯(cuò)和自動(dòng)補(bǔ)全示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Spring實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離詳解

    Spring實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離詳解

    這篇文章主要介紹了Spring?實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離,大多數(shù)系統(tǒng)都是讀多寫少,為了降低數(shù)據(jù)庫的壓力,可以對(duì)主庫創(chuàng)建多個(gè)從庫,從庫自動(dòng)從主庫同步數(shù)據(jù),程序中將寫的操作發(fā)送到主庫,將讀的操作發(fā)送到從庫去執(zhí)行,需要的朋友可以參考下
    2024-01-01
  • MyBatis如何實(shí)現(xiàn)流式查詢的示例代碼

    MyBatis如何實(shí)現(xiàn)流式查詢的示例代碼

    這篇文章主要介紹了MyBatis 如何實(shí)現(xiàn)流式查詢的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • java實(shí)現(xiàn)301跳轉(zhuǎn)和重定向的方法

    java實(shí)現(xiàn)301跳轉(zhuǎn)和重定向的方法

    301跳轉(zhuǎn)和重定向是做項(xiàng)目的時(shí)候經(jīng)常需要用到的,本文給大家分享的是在java中301跳轉(zhuǎn)和重定向的方法,需要的小伙伴參考下吧。
    2015-03-03
  • java實(shí)現(xiàn)簡單登錄界面的實(shí)戰(zhàn)過程

    java實(shí)現(xiàn)簡單登錄界面的實(shí)戰(zhàn)過程

    學(xué)習(xí)JAVA的過程當(dāng)中,登陸界面是多數(shù)人第一個(gè)實(shí)現(xiàn)的小程序,下面這篇文章主要給大家介紹了關(guān)于利用java實(shí)現(xiàn)簡單登錄界面的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • springboot項(xiàng)目事務(wù)標(biāo)簽驗(yàn)證

    springboot項(xiàng)目事務(wù)標(biāo)簽驗(yàn)證

    本文主要介紹了springboot項(xiàng)目事務(wù)標(biāo)簽驗(yàn)證,文中通過示例代碼介紹的非常詳細(xì),詳細(xì)的介紹了不加事務(wù)標(biāo)簽和加事物標(biāo)簽的使用,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • spring MVC實(shí)踐需要注意的地方

    spring MVC實(shí)踐需要注意的地方

    這篇文章主要介紹了spring MVC實(shí)踐需要注意的地方,幫助大家更好的理解和學(xué)習(xí)使用spring MVC,感興趣的朋友可以了解下
    2021-03-03
  • Java中快速把map轉(zhuǎn)成json格式的方法

    Java中快速把map轉(zhuǎn)成json格式的方法

    這篇文章主要介紹了Java中快速把map轉(zhuǎn)成json格式的方法,本文使用json-lib.jar中的JSONSerializer.toJSON方法實(shí)現(xiàn)快速把map轉(zhuǎn)換成json,需要的朋友可以參考下
    2015-07-07

最新評(píng)論