byteBuffer_bytebuffer.wrap

byteBuffer_bytebuffer.wrap引言在nio中,流的读取和写入都是依赖buffer的。jdk在nio包中提供了ByteBuffer、CharBuffer、ShortBuffer、LongBuffer、DoubleBuffer、FloatBuffer等。6中类型的buffer还分为两种实现,缓存在jvm堆中和缓存在直接内存中。Buffer主要属性//Invariants:mark<=position&lt…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

引言

在nio中,流的读取和写入都是依赖buffer的。jdk在nio包中提供了ByteBuffer、CharBuffer、ShortBuffer、LongBuffer、DoubleBuffer、FloatBuffer等。 6中类型的buffer还分为两种实现,缓存在jvm堆中和缓存在直接内存中。

Buffer

主要属性

// Invariants: mark <= position <= limit <= capacity
    private int mark = -1;
    private int position = 0;
    private int limit;
    private int capacity;

    // Used only by direct buffers
    // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
    long address;

主要方法

这些方法是用来控制buffer的读写。
jdk提供的buffer只有一个position指针,读和写都是从position的位置开始操作。
代码的流程常常是这样的:
buffer.put(1);
buffer.flip();
buffer.get();
用于多次读取操作

public final Buffer mark() { 
   
        mark = position;
        return this;
    }

public final Buffer reset() { 
   
        int m = mark;
        if (m < 0)
            throw new InvalidMarkException();
        position = m;
        return this;
    }

假装清空

public final Buffer clear() { 
   
        position = 0;
        limit = capacity;
        mark = -1;
        return this;
    }

翻转指针

public final Buffer flip() { 
   
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }

剩余容量

public final int remaining() { 
   
        return limit - position;
    }

获取读写指针的方法

final int nextGetIndex() { 
                             // package-private
        if (position >= limit)
            throw new BufferUnderflowException();
        return position++;
    }

final int nextPutIndex() { 
                             // package-private
        if (position >= limit)
            throw new BufferOverflowException();
        return position++;
    }

ByteBuffer

主要属性

// byte数组
final byte[] hb;                  // Non-null only for heap buffers
// offset 在派生的时候有用
    final int offset;

实例化方法

创建指定容量的heapBuffer和directBuffer

public static ByteBuffer allocate(int capacity) { 
   
        if (capacity < 0)
            throw new IllegalArgumentException();
        return new HeapByteBuffer(capacity, capacity);
    }

public static ByteBuffer allocateDirect(int capacity) { 
   
        return new DirectByteBuffer(capacity);
    }

通过数组创建ByteBuffer

public static ByteBuffer wrap(byte[] array,
                                    int offset, int length)
    { 
   
        try { 
   
            return new HeapByteBuffer(array, offset, length);
        } catch (IllegalArgumentException x) { 
   
            throw new IndexOutOfBoundsException();
        }
    }

put和get方法

public ByteBuffer put(byte x) { 
   
		
		// 获取put的指针 
        hb[ix(nextPutIndex())] = x;
        return this;
    }

public byte get() { 
   
		// 获取get的指针
        return hb[ix(nextGetIndex())];
    }

protected int ix(int i) { 
   
        return i + offset;
    }

派生ByteBuffer
slice创建的Buffer,读写都是在数组的子序列上进行。依赖于Buffer的当前索引

// 共享数组,position=0 mark=-1 limit=cap,
public ByteBuffer slice() { 
   
        return new HeapByteBuffer(hb,
                                        -1,
                                        0,
                                        this.remaining(),
                                        this.remaining(),
                                        this.position() + offset);
    }

复制一个对象,共享数组,拥有相同数值的mark、position、limit、capacity和offset

public ByteBuffer duplicate() { 
   
        return new HeapByteBuffer(hb,
                                        this.markValue(),
                                        this.position(),
                                        this.limit(),
                                        this.capacity(),
                                        offset);
    }

把已经在本buffer写的元素移动到0位置,position定位到剩余容量起点,limit限制为capacity

public ByteBuffer compact() { 
   
        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
        position(remaining());
        limit(capacity());
        discardMark();
        return this;
    }

常用代码段

// 拷贝文件
public void copyFile(String copyFrom,String copyTo){ 

File file = new File(copyFrom);
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
FileChannel channel = randomAccessFile.getChannel();
File outFile = new File(copyTo);
RandomAccessFile outRAF = new RandomAccessFile(outFile, "rw");
FileChannel outChannel = outRAF.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (channel.read(byteBuffer) > 0){ 

while (byteBuffer.hasRemaining()){ 

byteBuffer.flip();
outChannel.write(byteBuffer);
}
}
}
// 从网络中读取文件
public void readNetworkFile(){ 

File outFile = new File("d://20200418220925641.png");
RandomAccessFile outRAF = new RandomAccessFile(outFile, "rw");
FileChannel outChannel = outRAF.getChannel();
// get stream from net
InputStream inputStream = new URL("https://img-blog.csdnimg.cn/20200418220925641.png").openConnection()
.getInputStream();
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
byte[] cache = new byte[2 * 1024];
ByteBuffer wrap = ByteBuffer.wrap(cache);
int len;
while ((len = bufferedInputStream.read(cache)) > 0){ 

wrap.position(0);
wrap.limit(len);
outChannel.write(wrap);
}
}
public void writeMsgToClient(){ 

ServerSocket serverSocket = new ServerSocket(9988);
// bad case
Socket accept = serverSocket.accept();
SocketChannel channel = accept.getChannel();
// do business logic and get a byte array
byte[] rlt = "businessLogicRlt".getBytes();
ByteBuffer wrap = ByteBuffer.wrap(rlt, 0, rlt.length);
channel.write(wrap);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/186804.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 七个开源的 SpringBoot 前后端分离项目,Star过千,快去收藏夹吃灰吧!

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 微信公众号:江南一点雨 前后端分离已经在慢慢走进各公司的技术栈,根据松哥了解到的消息,不少公司都已经切换到这个技术栈…

  • stm32的语音识别_基于STM32的嵌入式语音识别模块设计

    stm32的语音识别_基于STM32的嵌入式语音识别模块设计引言服务机器人以服务为目的,因此人们需要一种更方便、更自然、更加人性化的方式与机器人交互,而不再满足于复杂的键盘和按钮操作。基于听觉的人机交互是该领域的一个重要发展方向。目前主流的语音识别技术是基于统计模式。然而,由于统计模型训练算法复杂,运算量大,一般由工控机、PC机或笔记本来完成,这无疑限制了它的运用。嵌入式语音交互已成为目前研究的热门课题。嵌入式语音识别系统和PC机的语音识别系统相比,虽然其…

  • SQL Server 2008 Express 及 SSMS Express 下载安装配置教程「建议收藏」

    SQL Server 2008 Express 及 SSMS Express 下载安装配置教程「建议收藏」这篇文章主要讲如何一步步从下载、安装、配置SQLServer2008Express和SMSS到最后使用SMSS连接本地的数据库服务。

  • 字符串数组转换为list集合

    字符串数组转换为list集合String[]arr={“a”,”C”,”abc”}; //asList该方法可以直接将一个数组转换为list集合,但是该集合是[只读的],不能对得到的集合进行增删改List<String>asList=Arrays.asList(arr);System.out.println(asList);//结果:[a,C,abc]Listlis…

  • RT-Thread中自定义 FinSH 命令「建议收藏」

    RT-Thread中自定义 FinSH 命令「建议收藏」在使用RT-Thread中的FinSH命令时,除了系统默认的FinSH命令以外,我们还可以自定义FinSH命令。下面就来演示一下如何自定义FinSH命令。关于FinSH命令的详细用法请参考官方资料https://www.rt-thread.org/document/site/programming-manual/finsh/finsh/。要使用FinSH命令首先要添加FinSH组件,添加组件的详细过程见手把手教你移植RT-Thread系统,FinSH组件添加成后,打开建立…

  • 批量梯度下降法(BGD)、随机梯度下降法(SGD)和小批量梯度下降法(MBGD)

    批量梯度下降法(BGD)、随机梯度下降法(SGD)和小批量梯度下降法(MBGD)梯度下降法作为机器学习中较常使用的优化算法,其有着三种不同的形式:批量梯度下降(BatchGradientDescent)、随机梯度下降(StochasticGradientDescent)以及小批量梯度下降(Mini-BatchGradientDescent)。其中小批量梯度下降法也常用在深度学习中进行模型的训练。接下来,我们将对这三种不同的梯度下降法进行理解。  为了便于理解,…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号