最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java BufferedOutputStream類的常用方法講解

 更新時(shí)間:2021年10月12日 11:41:33   作者:scbiaosdo  
這篇文章主要介紹了Java BufferedOutputStream類的常用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

BufferedOutputStream類的常用方法

BufferedOutputStream字節(jié)緩沖輸出流

構(gòu)造方式

第一種開發(fā)中

public BufferedOutputStream(OutputStream out)

采用的默認(rèn)的緩沖區(qū)大小(足夠大了) ,來(lái)構(gòu)造一個(gè)字節(jié)緩沖輸出流對(duì)象

public BufferedOutputStream(OutputStream out,int size)

指定size緩沖區(qū)大小構(gòu)造緩沖輸出流對(duì)象

IllegalArgumentException - 如果 size <= 0

常用方法

public void write(int b)throws IOException

一次寫一個(gè)字節(jié)

  • b - 要寫入的字節(jié)。
public void write(byte[] b,int off,int len) throws IOException

一次寫一個(gè)字節(jié)數(shù)組的一部分

  • b - 數(shù)據(jù)。
  • off - 數(shù)據(jù)的起始偏移量。
  • len - 要寫入的字節(jié)數(shù)。
public void flush() throws IOException

刷新此緩沖的輸出流。這迫使所有緩沖的輸出字節(jié)被寫出到底層輸出流中。

public void close() throws IOException

關(guān)閉此輸出流并釋放與此流有關(guān)的所有系統(tǒng)資源。

FilterOutputStream 的 close 方法先調(diào)用其 flush 方法,然后調(diào)用其基礎(chǔ)輸出流的 close 方法。

程序示例

public static void main(String[] args) throws Exception {    
    //符合Java一種設(shè)計(jì)模式:裝飾者設(shè)計(jì)模式(過(guò)濾器:Filter)
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt")) ;        
    //寫數(shù)據(jù)
    bos.write("hello".getBytes());
    //釋放資源
    bos.close();
}

BufferedOutputStream深入分析

FileOutputStream和BufferedOutputStream都提供了一系列的將數(shù)據(jù)寫入文件的方式,并且我們都知道BufferedOutputStream要比直接使用FileOutputStream寫入速度要快,本文通過(guò)案例實(shí)際演示一下兩者的區(qū)別。

代碼準(zhǔn)備

public class BufferFile {
    public static void main(String[] args) {
        //每次向文件中寫入一個(gè)8字節(jié)的數(shù)組
        byte[] bytes = "1234567\n".getBytes();
        //每隔100毫秒通過(guò)buffer的方式向文件中寫入數(shù)據(jù)
        new Thread(() -> {
            System.out.println("buffer_while start...");
            File file = new File("/var/file_test_data/out_buffer_while.txt");
            FileOutputStream fileOutputStream;
            try {
                fileOutputStream = new FileOutputStream(file);
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                while (true) {
                    Thread.sleep(100);
                    bufferedOutputStream.write(bytes);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        //通過(guò)buffer的方式向文件中寫入1千萬(wàn)次
        new Thread(() -> {
            System.out.println("buffer_for start...");
            File file = new File("/var/file_test_data/out_buffer_for.txt");
            FileOutputStream fileOutputStream;
            try {
                fileOutputStream = new FileOutputStream(file);
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                for (int i = 0; i < 10000000; i++) {
                    bufferedOutputStream.write(bytes);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(new Date() + ": buffer_for end...");
        }).start();
        //通過(guò)file的方式向文件中寫入1千萬(wàn)次
        new Thread(() -> {
            System.out.println("file_for start...");
            File file = new File("/var/file_test_data/out_file_for.txt");
            FileOutputStream fileOutputStream;
            try {
                fileOutputStream = new FileOutputStream(file);
                for (int i = 0; i < 10000000; i++) {
                    fileOutputStream.write(bytes);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(new Date() + ": file_for end...");
        }).start();
    }
}

開始運(yùn)行

在這里插入圖片描述

強(qiáng)行停止后的運(yùn)行結(jié)果

在這里插入圖片描述

1、file和buffe寫入速度比較

兩者分別寫入1千萬(wàn)次,時(shí)間上buffer比f(wàn)ile快8秒,如果當(dāng)寫入次數(shù)指數(shù)級(jí)增加時(shí),buffer的優(yōu)勢(shì)將更加明顯。

2、數(shù)據(jù)寫入完整性問(wèn)題

buffer雖然要比f(wàn)ile快,但是從最終數(shù)據(jù)上可以看出,buffer會(huì)丟數(shù)據(jù)

  • 當(dāng)?shù)谝粋€(gè)線程寫入時(shí)數(shù)據(jù)還未滿8kb時(shí),強(qiáng)制停止java進(jìn)程,最終out_buffer_while.txt沒有數(shù)據(jù)。
  • 第二個(gè)線程,雖然最終代碼執(zhí)行完畢,但是比較file方式,out_buffer_for.txt文件看起來(lái)也丟了一部分?jǐn)?shù)據(jù)。

原因分析

當(dāng)使用buffer讀寫文件時(shí),數(shù)據(jù)并沒有直接被寫入磁盤,而是被緩存到一個(gè)字節(jié)數(shù)據(jù)中,這個(gè)字節(jié)數(shù)組的大小是8kb,默認(rèn)情況下只有當(dāng)8kb被填充滿了以后,數(shù)據(jù)才會(huì)被一次性寫入磁盤,這樣一來(lái)就大大減少了系統(tǒng)調(diào)用的次數(shù)(file是每一次write都會(huì)產(chǎn)生系統(tǒng)調(diào)用),當(dāng)然也正是因?yàn)閎uffer中的每一次write只是寫入到內(nèi)存中(JVM自身內(nèi)存中),所以當(dāng)數(shù)據(jù)未寫入磁盤前,如果JVM進(jìn)程掛了,那么就會(huì)造成數(shù)據(jù)丟失。

手動(dòng)刷盤

為了解決數(shù)據(jù)丟失的問(wèn)題,buf中提供了flush()方法,用戶可以自行決定合適將數(shù)據(jù)刷寫到磁盤中

  • 如果你的flush()調(diào)用的非常頻繁,那就會(huì)退化為普通的file模式了。
  • 如果你的flush()調(diào)用的又不太頻繁,那么丟數(shù)據(jù)的可能性就比較高。
  • 無(wú)論如何業(yè)務(wù)邏輯中數(shù)據(jù)寫完時(shí),一定要調(diào)用一次flush(),確保緩沖區(qū)的數(shù)據(jù)刷到磁盤上。

將無(wú)限循環(huán)寫入的代碼注釋掉,在buf寫1千萬(wàn)完成后,加上bufferedOutputStream.flush();

public class BufferFile {
    public static void main(String[] args) {
        //每次向文件中寫入一個(gè)8字節(jié)的數(shù)組
        byte[] bytes = "1234567\n".getBytes();
        //每隔100毫秒通過(guò)buffer的方式向文件中寫入數(shù)據(jù)
        /*new Thread(() -> {
            System.out.println("buffer_while start...");
            File file = new File("/var/file_test_data/out_buffer_while.txt");
            FileOutputStream fileOutputStream;
            try {
                fileOutputStream = new FileOutputStream(file);
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                while (true) {
                    Thread.sleep(100);
                    bufferedOutputStream.write(bytes);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();*/
        //通過(guò)buffer的方式向文件中寫入1千萬(wàn)次
        new Thread(() -> {
            System.out.println("buffer_for start...");
            File file = new File("/var/file_test_data/out_buffer_for.txt");
            FileOutputStream fileOutputStream;
            try {
                fileOutputStream = new FileOutputStream(file);
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                for (int i = 0; i < 10000000; i++) {
                    bufferedOutputStream.write(bytes);
                }
                bufferedOutputStream.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(new Date() + ": buffer_for end...");
        }).start();
        //通過(guò)file的方式向文件中寫入1千萬(wàn)次
        new Thread(() -> {
            System.out.println("file_for start...");
            File file = new File("/var/file_test_data/out_file_for.txt");
            FileOutputStream fileOutputStream;
            try {
                fileOutputStream = new FileOutputStream(file);
                for (int i = 0; i < 10000000; i++) {
                    fileOutputStream.write(bytes);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(new Date() + ": file_for end...");
        }).start();
    }
}

這次再看數(shù)據(jù)寫入完整了

在這里插入圖片描述

buffer源碼分析

類的機(jī)構(gòu)圖

在這里插入圖片描述

首先當(dāng)創(chuàng)建一個(gè)BufferedOutputStream對(duì)象時(shí),構(gòu)造方法就初始化了緩沖的字節(jié)數(shù)組大小為8kb

	protected byte buf[];
    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }
    public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

當(dāng)調(diào)用buffer.write(b)時(shí),調(diào)用的是父類FilterOutputStream的方法

    public void write(byte b[]) throws IOException {
    	//寫入的字節(jié)數(shù)組b,從0開始,一共要寫入的長(zhǎng)度
        write(b, 0, b.length);
    }
    	
    public void write(byte b[], int off, int len) throws IOException {
        if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
            throw new IndexOutOfBoundsException();
		//遍歷數(shù)組,一個(gè)字節(jié)一個(gè)字節(jié)的把數(shù)據(jù)寫入數(shù)組中
        for (int i = 0 ; i < len ; i++) {
            write(b[off + i]);
        }
    }
    
    public synchronized void write(int b) throws IOException {
    	//判斷字節(jié)長(zhǎng)度是否超過(guò)buf.length,buf在初始化已經(jīng)指定大小為8192,即8kb
    	//如果超過(guò)則調(diào)用flushBuffer
        if (count >= buf.length) {
            flushBuffer();
        }
        把每一個(gè)字節(jié)寫入緩沖的buf數(shù)組中,并且統(tǒng)計(jì)值count++
        buf[count++] = (byte)b;
    }
    private void flushBuffer() throws IOException {
        if (count > 0) {
        	//真正的調(diào)用OutputStream,寫入數(shù)據(jù)到磁盤中
        	//寫入buf緩沖字節(jié)數(shù)組數(shù)據(jù),從0下標(biāo)開始,一直寫到count,即有多少寫多少。
            out.write(buf, 0, count);
            count = 0;
        }
    }

關(guān)于buf緩沖數(shù)據(jù)大小設(shè)置

buffer提供了可以自定義緩沖大小的構(gòu)造方法

    public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

如果緩沖大小設(shè)置的比較大。

  • 好處:進(jìn)一步減少調(diào)用系統(tǒng)內(nèi)核寫數(shù)據(jù)的方法,提高寫入速度,kafka的批寫入默認(rèn)就是16kb寫一次。
  • 壞處:1、丟失的數(shù)據(jù)可能會(huì)更多,2、要注意堆內(nèi)存的消耗。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 通過(guò)實(shí)例學(xué)習(xí)JAVA對(duì)象轉(zhuǎn)成XML輸出

    通過(guò)實(shí)例學(xué)習(xí)JAVA對(duì)象轉(zhuǎn)成XML輸出

    這篇文章主要介紹了通過(guò)實(shí)例學(xué)習(xí)JAVA對(duì)象轉(zhuǎn)成XML輸出,做流程圖的項(xiàng)目時(shí),新的流程定義為xml的,需要對(duì)xml與java對(duì)象進(jìn)行互轉(zhuǎn),下面我們來(lái)深入學(xué)習(xí),需要的朋友可以參考下
    2019-06-06
  • 基于Java和XxlCrawler獲取各城市月度天氣情況實(shí)踐分享

    基于Java和XxlCrawler獲取各城市月度天氣情況實(shí)踐分享

    本文主要講解使用Java開發(fā)語(yǔ)言,使用XxlCrawler框架進(jìn)行智能的某城市月度天氣抓取實(shí)踐開發(fā),文章首先介紹目標(biāo)網(wǎng)站的相關(guān)頁(yè)面及目標(biāo)數(shù)據(jù)的元素,然后講解在信息獲取過(guò)程的一些參數(shù)配置以及問(wèn)題應(yīng)對(duì),需要的朋友可以參考下
    2024-05-05
  • 關(guān)于@RequestParam的使用所遇到的404問(wèn)題

    關(guān)于@RequestParam的使用所遇到的404問(wèn)題

    這篇文章主要介紹了關(guān)于@RequestParam的使用所遇到的404問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • spring boot集成rabbitmq的實(shí)例教程

    spring boot集成rabbitmq的實(shí)例教程

    這篇文章主要給大家介紹了關(guān)于spring boot集成rabbitmq的相關(guān)資料,springboot集成RabbitMQ非常簡(jiǎn)單,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • springMVC返回復(fù)雜的json格式數(shù)據(jù)方法

    springMVC返回復(fù)雜的json格式數(shù)據(jù)方法

    下面小編就為大家分享一篇springMVC返回復(fù)雜的json格式數(shù)據(jù)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • 一文講解Java的String、StringBuffer和StringBuilder的使用與區(qū)別

    一文講解Java的String、StringBuffer和StringBuilder的使用與區(qū)別

    String是不可變的字符序列,而StringBuffer和StringBuilder是可變的字符序列,本文就來(lái)詳細(xì)的介紹一下Java的String、StringBuffer和StringBuilder的使用與區(qū)別,感興趣的可以了解一下
    2024-03-03
  • 如何配置cursor進(jìn)行Java springboot項(xiàng)目開發(fā)

    如何配置cursor進(jìn)行Java springboot項(xiàng)目開發(fā)

    本文介紹了如何在Cursor IDE中配置Java和Spring Boot項(xiàng)目開發(fā)環(huán)境,首先,設(shè)置了系統(tǒng)用戶級(jí)別的JDK配置,以便在多個(gè)項(xiàng)目之間切換時(shí)不需要重新配置,然后,配置了Gradle環(huán)境變量,并安裝了必要的Java開發(fā)插件,感興趣的朋友跟隨小編一起看看
    2025-02-02
  • java中字符串如何計(jì)算字節(jié)長(zhǎng)度

    java中字符串如何計(jì)算字節(jié)長(zhǎng)度

    這篇文章主要介紹了java中字符串如何計(jì)算字節(jié)長(zhǎng)度,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 關(guān)于@Autowired的使用及注意事項(xiàng)

    關(guān)于@Autowired的使用及注意事項(xiàng)

    這篇文章主要介紹了關(guān)于@Autowired的使用及注意事項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java基于Guava Retrying實(shí)現(xiàn)重試功能

    Java基于Guava Retrying實(shí)現(xiàn)重試功能

    這篇文章主要介紹了Java基于Guava Retrying實(shí)現(xiàn)重試功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07

最新評(píng)論

弥勒县| 曲靖市| 嵊泗县| 禄劝| 莫力| 滨州市| 中牟县| 台江县| 前郭尔| 永丰县| 平果县| 磐石市| 金湖县| 高邑县| 从化市| 青铜峡市| 江津市| 久治县| 临颍县| 监利县| 兴山县| 鲁山县| 马龙县| 瑞昌市| 宜都市| 锡林浩特市| 盐边县| 光泽县| 阳原县| 长顺县| 林口县| 罗定市| 灯塔市| 平邑县| 甘南县| 八宿县| 苍南县| 会理县| 贺兰县| 收藏| 萝北县|