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

java nio中的ByteBuffer擴(kuò)展問題

 更新時(shí)間:2023年08月21日 10:36:37   作者:???潪??  
這篇文章主要介紹了java nio中的ByteBuffer擴(kuò)展問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

前言

在jdk1.4之前對(duì)于輸入輸出只能使用InPutStream和outPutSream這類傳統(tǒng)io模型,在jdk1.4之后新增了nio,什么是nio?

nio是new input/output 的簡(jiǎn)稱,nio的效率要比傳統(tǒng)io效率高,主要原因就是nio利用了系統(tǒng)底層的零拷貝技術(shù)和多路復(fù)用技術(shù)。

NIO核心知識(shí)

NIO有三個(gè)核心概念

  • 1、Channal通道
  • 2、Buffer緩沖
  • 3、Selector選擇器

以上三者之間的關(guān)系是,一個(gè)線程擁有一個(gè)selector選擇器,一個(gè)selector選擇器管理多個(gè)channel通道,每個(gè)channel通道具有一個(gè)Buffer緩沖。為了更好的理解nio這三者之間的關(guān)系。舉一個(gè)實(shí)際生活中遇到的例子。

公司一般每年都會(huì)提供免費(fèi)的體檢,一般都是和愛康國(guó)賓合作的,去體檢了幾次發(fā)現(xiàn)一個(gè)有趣的事情:

1、客戶很多、體檢項(xiàng)目也很多。但是客戶不知道自己應(yīng)該去哪個(gè)房間體檢。

2、體檢中心提供一個(gè)中轉(zhuǎn)中心,中轉(zhuǎn)中心四周都是體檢房間,所有的人在每項(xiàng)體檢后都要經(jīng)過這個(gè)中轉(zhuǎn)中心。

3、每個(gè)體檢者手里都要握著一個(gè)體檢單。體檢單上會(huì)有自己的體檢項(xiàng)目。

4、中轉(zhuǎn)中心有一個(gè)工作人員(引導(dǎo)員),每個(gè)體檢人員來到中轉(zhuǎn)中心,引導(dǎo)員會(huì)結(jié)合體檢房間的空閑情況和體檢者的體檢單來指定具體要去的體檢場(chǎng)所。

5、體檢速度快,不會(huì)產(chǎn)生太長(zhǎng)的隊(duì)伍,比較高效的方式。

那這個(gè)這里里面有幾個(gè)角色完全可以對(duì)應(yīng)nio中的三個(gè)概念,分別是,引導(dǎo)員=selector, 體檢者手上的體檢單=Buffer, 每個(gè)體檢者=channel;

ByteBuffer

ByteBuffer是Buffer的一個(gè)子類,實(shí)現(xiàn)方式類似byte[], 該類有個(gè)重要的概念就是指針,指針標(biāo)志的位置代表下次操作的位置。

ByteBuffer分為讀模式和寫模式,當(dāng)然了這種稱謂都是人們習(xí)慣性的稱呼,其實(shí)只是指針指向的區(qū)別,比如讀模式指針指向數(shù)組下標(biāo)為0的位置,寫模式指針指向數(shù)組最后一位。

在實(shí)際使用中一個(gè)byteBuffer可能需要被反復(fù)讀取多次,于是byteBuffer提供了mark()方法,mark方法標(biāo)記的下標(biāo)供reset方法使用。

如果當(dāng)前byteBuffer中存儲(chǔ)的是[a,b,c,d,e]這五個(gè)字符,讀取的時(shí)候讀取到c的時(shí)候調(diào)用了mark()方法添加了標(biāo)記,那么當(dāng)讀取到e時(shí),又想從標(biāo)記的地方重新讀取時(shí),只需要調(diào)用reset()即可將指針指向c的位置,ByteBuffer提供的方法雖然很好,但是在日常使用的時(shí)候還是不太方便,比如在b處打了標(biāo)記,當(dāng)讀取到c時(shí)又打了標(biāo)記,目的時(shí)要從c處重新讀取一遍,然后再?gòu)腷處重新讀取一遍,這是byteBuffer就顯得有些不太好使了。

筆者寫了一個(gè)擴(kuò)展byteBuffer的類

代碼如下:

package pers.cz.tools;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
 * @program: Reids
 * @description: 擴(kuò)展ByteBuffer,提供多次標(biāo)記的功能。
 * @author: Cheng Zhi
 * @create: 2023-04-13 20:23
 **/
public class JefByteBuffer {
    /**
     * 保存所有的標(biāo)記點(diǎn)
     */
    private int[] markPocket = new int[16];
    ByteBuffer byteBuffer;
    private int index = 0;
    public JefByteBuffer(int capacity, boolean isUseLocalMem) {
        if (isUseLocalMem) {
            byteBuffer = ByteBuffer.allocateDirect(capacity);
        } else {
            byteBuffer =  ByteBuffer.allocate(capacity);
        }
    }
    public JefByteBuffer(ByteBuffer byteBuffer) {
        this.byteBuffer = byteBuffer;
    }
    /**
     * 切換模式
     */
    public Buffer flip() {
       return byteBuffer.flip();
    }
    public char read() {
        return (char) byteBuffer.get();
    }
    public void unread() {
        int position = byteBuffer.position();
        byteBuffer.position(position - 1);
    }
    public byte get() {
        return byteBuffer.get();
    }
    public void put(byte[] src) {
        byteBuffer.put(src);
    }
    public void put(byte bi) {
        byteBuffer.put(bi);
    }
    public void clear() {
        byteBuffer.clear();
    }
    public boolean isEnd() {
        int current = byteBuffer.position();
        int end = byteBuffer.limit();
        if (current == end) {
            return true;
        }
        return false;
    }
    /**
     * 打標(biāo)記
     */
    public void mark() {
        int mark = byteBuffer.position();
        ensureCapacityInternal();
        markPocket[index] = mark;
        index ++;
    }
    /**
     * 去除標(biāo)記
     */
    public void unmark() {
        index --;
        markPocket[index] = 0;
    }
    /**
     * 重置
     */
    public void reset() {
        index --;
        if (index < 0) {
            return;
        }
        int mark = markPocket[index];
        if (mark < 0) {
            return;
        }
        byteBuffer.position(mark);
    }
    /**
     * 為markPocket擴(kuò)容
     */
    private void ensureCapacityInternal() {
        int oldCapacity = markPocket.length;
        if (index >= oldCapacity) {
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            // minCapacity is usually close to size, so this is a win:
            markPocket = Arrays.copyOf(markPocket, newCapacity);
        }
    }
}

使用方式:

public static void test2() {
        JefByteBuffer jefByteBuffer = new JefByteBuffer(100);
        jefByteBuffer.put(new byte[] {'1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t'});
        jefByteBuffer.flip();
        for (int i=1; i<21; i++) {
            if (i == 1) {
                jefByteBuffer.mark();
            }
            if (i == 3) {
                jefByteBuffer.mark();
            }
            if (i == 5) {
                jefByteBuffer.mark();
            }
            if (i == 7) {
                jefByteBuffer.mark();
            }
            if (i == 9) {
                jefByteBuffer.mark();
            }
            if (i == 10) {
                jefByteBuffer.unmark();
            }
            if (i == 11) {
                //jefByteBuffer.unmark();
                // 這里將回到i=7的標(biāo)記點(diǎn)
                jefByteBuffer.reset();
            }
/*            if (i ==8) {
                jefByteBuffer.reset();
            }*/
            char b = (char) jefByteBuffer.read();
            jefByteBuffer.unread();
            System.out.println(b);
        }
    }

這樣在使用byteBuffer的時(shí)候就可以靈活的讀取,方法名更是見名知意,比如read讀取了一個(gè)字節(jié)之后,調(diào)用unread后還可以重新讀取。

總結(jié)

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

相關(guān)文章

  • 通過實(shí)例解析傳統(tǒng)jar包引用方式

    通過實(shí)例解析傳統(tǒng)jar包引用方式

    這篇文章主要介紹了通過實(shí)例解析傳統(tǒng)jar包引用方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • SpringBoot?Loki安裝簡(jiǎn)介及實(shí)戰(zhàn)思路

    SpringBoot?Loki安裝簡(jiǎn)介及實(shí)戰(zhàn)思路

    這篇文章主要為大家介紹了SpringBoot?Loki安裝簡(jiǎn)介及實(shí)戰(zhàn)思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪的相關(guān)資料
    2022-11-11
  • Spring的@Configuration使用與原理

    Spring的@Configuration使用與原理

    這篇文章主要介紹了Spring的@Configuration使用與原理,@Configuration用于定義配置類,可替換xml配置文件,被注解的類內(nèi)部包含有一個(gè)或多個(gè)被@Bean注解的方法,需要的朋友可以參考下
    2023-05-05
  • Java裁剪壓縮PNG圖片,透明背景色變黑的解決方案

    Java裁剪壓縮PNG圖片,透明背景色變黑的解決方案

    這篇文章主要介紹了Java裁剪壓縮PNG圖片,透明背景色變黑的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java設(shè)計(jì)模式單例模式(Singleton)用法解析

    Java設(shè)計(jì)模式單例模式(Singleton)用法解析

    這篇文章主要介紹了Java設(shè)計(jì)模式單例模式(Singleton)用法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 解析SpringBoot整合SpringDataRedis的過程

    解析SpringBoot整合SpringDataRedis的過程

    這篇文章主要介紹了SpringBoot整合SpringDataRedis的過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • SpringBoot 使用 Maven 打包方式

    SpringBoot 使用 Maven 打包方式

    maven打包有三種方式 pom、jar、war,本篇文章給大家介紹SpringBoot 使用 Maven 打包方式,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • Java中的鎖分類的詳細(xì)介紹

    Java中的鎖分類的詳細(xì)介紹

    這篇文章主要介紹了Java中的鎖分類的詳細(xì)介紹,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • spring @Profiles和@PropertySource實(shí)現(xiàn)根據(jù)環(huán)境切換配置文件

    spring @Profiles和@PropertySource實(shí)現(xiàn)根據(jù)環(huán)境切換配置文件

    這篇文章主要介紹了spring @Profiles和@PropertySource根據(jù)環(huán)境切換配置文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Kafka源碼系列教程之刪除topic

    Kafka源碼系列教程之刪除topic

    這篇文章主要給大家介紹了關(guān)于Kafka源碼系列教程之刪除topic的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08

最新評(píng)論

开封市| 惠来县| 万州区| 健康| 洛川县| 海宁市| 平陆县| 岐山县| 宁明县| 南部县| 长海县| 乃东县| 行唐县| 库尔勒市| 四平市| 黔南| 鸡东县| 若尔盖县| 巴东县| 沐川县| 麻江县| 伊春市| 德阳市| 庆阳市| 平罗县| 平罗县| 伊春市| 固安县| 微山县| 花莲县| 肥东县| 菏泽市| 铜川市| 鄱阳县| 禄丰县| 元阳县| 徐汇区| 北安市| 兴国县| 修武县| 永登县|