Java之Buffer属性案例详解

 更新时间:2021年08月09日 09:52:01   作者:pengjunlee  
这篇文章主要介绍了Java之Buffer属性案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

一、前言

熟悉NIO的人想必一定不会陌生buffer中position,limit,capacity这三个属性吧,之前在学习的时候遇到一个问题:就是当你先往缓冲区写入一部分数据,然后调用flip()方法,再全部读取完数据,然后再调用flip()方法,此时这三个值的变化是怎样的,研究了一下,决定写下来分享一下。

二、正文

1、介绍

  • position: 它指的是下一次读取或写入的位置。
  • limit: 指定还有多少数据需要写出(在从缓冲区写入通道时),或者还有多少空间可以读入数据(在从通道读入缓冲区时),它初始化是与capacity的值一样,当调用flip()方法之后,它的值会改变成position的值,而position被置0。它箭头所指的位置是最后一位元素的下一位所在的位置*
  • capacity: 指定了可以存储在缓冲区中的最大数据容量,实际上,它指定了底层数组的大小,或者至少是指定了准许我们使用的底层数组的容量,这个初始化后就不会再改变了。

2、图示

以上三个属性值之间有一些相对大小的关系:0 <= position <= limit <= capacity。如果我们创建一个新的容量大小为7的ByteBuffer对象,在初始化的时候,position设置为0,limit和 capacity被设置为7,在以后使用ByteBuffer对象过程中,capacity的值不会再发生变化,而其它两个个将会随着使用而变化。三个属性值分别如图所示:

初始化:

假设我们现在要往这个缓冲区里面写入3个字节,写完之后,position的箭头就会指向3的位置,而limit不变:

此时我们想从缓冲区读取这3个字节,就必须调用flip()方法,调用了flip()方法过后,limit置为position的位置,而position被置为0,也正应证了上面所说的,position它指的是下一次读取或写入的位置,limit它箭头所指的位置是最后一位元素的下一位所在的位置:

现在我们可以调用get()方法,一直从缓冲区里面取数据,直到取完为止,也就是当position与limit的值一样时,就取完了:

这一次简单的读写操作就完成了,如果想恢复成初始状态的话,可以调用clear()方法:

之前学到这里的时候有个疑问,不知道大家想过没有,就是我们在调用了get()方法从缓冲区取完里面的数据,立马去调用flip()方法,那这三个属性的值会是什么变化?如果当我只读了2个字节的数据之后,就不读了,然后再去调用flip(),这三个值又会是怎么变化?其实不管怎么绕,你只要懂得原理,就不难,咱们先看flip()源代码做了什么:

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

这里不难发现,调用flip()方法,无非就是给这几个变量赋值,将当前的position值赋给limit,然后将position的值置为0,Mark是一个标志变量,咱们以后会提到。熟悉以上代码就不难解决我提出的2个问题:

  • 当你读取完调用flip()的方法      positon:0    limit:3       capacity:7
  • 当你读取2个字节之后调用flip()方法       positon:0    limit:2       capacity:7

这里就解决了我之前遇到的这三个属性值变化的问题!!!

三、测试代码

读取完调用flip:

package com.cing.nio;
 
import java.io.FileInputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
 
public class NioTest1 {
    public static void main(String[] args) throws Exception{
 
        FileInputStream fis = new FileInputStream("D:\\A.txt");
        FileChannel fc = fis.getChannel();
 
        ByteBuffer buffer = ByteBuffer.allocate(7);
        output("初始化", buffer);
 
        fc.read(buffer);
        output("调用READ方法", buffer);
 
        buffer.flip();
        output("第一次调用flip", buffer);
 
        while (buffer.remaining() > 0) {
            byte b = buffer.get();
        }
        output("get()", buffer);
 
        buffer.flip();
        output("第二次flip", buffer);
 
        fis.close();
    }
 
    public static void output(String step, Buffer buffer) {
        System.out.println(step + " : ");
        System.out.println("buffer: " + buffer + ", ");
    }
}
 
 

输出结果为:

初始化 : 
buffer: java.nio.HeapByteBuffer[pos=0 lim=7 cap=7], 
调用READ方法 : 
buffer: java.nio.HeapByteBuffer[pos=3 lim=7 cap=7], 
第一次调用flip : 
buffer: java.nio.HeapByteBuffer[pos=0 lim=3 cap=7], 
get() : 
buffer: java.nio.HeapByteBuffer[pos=3 lim=3 cap=7], 
第二次flip : 
buffer: java.nio.HeapByteBuffer[pos=0 lim=3 cap=7], 

读取2字节之后调用flip:

package com.cing.nio;
 
import java.io.FileInputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
 
public class NioTest1 {
    public static void main(String[] args) throws Exception{
 
        FileInputStream fis = new FileInputStream("D:\\A.txt");
        FileChannel fc = fis.getChannel();
 
        ByteBuffer buffer = ByteBuffer.allocate(7);
        output("初始化", buffer);
 
        fc.read(buffer);
        output("调用READ方法", buffer);
 
        buffer.flip();
        output("第一次调用flip", buffer);
 
        while (buffer.remaining() > 1) {
            byte b = buffer.get();
        }
        output("get()", buffer);
 
        buffer.flip();
        output("第二次flip", buffer);
 
        fis.close();
    }
 
    public static void output(String step, Buffer buffer) {
        System.out.println(step + " : ");
        System.out.println("buffer: " + buffer + ", ");
    }
}
 

输出结果为:

初始化 : 
buffer: java.nio.HeapByteBuffer[pos=0 lim=7 cap=7], 
调用READ方法 : 
buffer: java.nio.HeapByteBuffer[pos=3 lim=7 cap=7], 
第一次调用flip : 
buffer: java.nio.HeapByteBuffer[pos=0 lim=3 cap=7], 
get() : 
buffer: java.nio.HeapByteBuffer[pos=2 lim=3 cap=7], 
第二次flip : 
buffer: java.nio.HeapByteBuffer[pos=0 lim=2 cap=7], 

NIO的知识学起来还是比较有趣的,期待下次与大家分享这块的知识!

到此这篇关于Java之Buffer属性案例详解的文章就介绍到这了,更多相关Java之Buffer属性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring boot项目打包成jar运行的二种方法

    Spring boot项目打包成jar运行的二种方法

    这篇文章主要给大家介绍了关于Spring boot项目打包成jar运行的二种方法,文中通过示例代码介绍的非常详细,对大家学习或者使用spring boot具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • Java中MessageDigest来实现数据加密的方法

    Java中MessageDigest来实现数据加密的方法

    这篇文章主要介绍了Java中MessageDigest来实现数据加密的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • javaCV视频处理之提取人像视频

    javaCV视频处理之提取人像视频

    这篇文章主要介绍了利用JavaCV实现提取视频中的人像并保存为视频,文中的示例代码讲解详细,对我们学习JavaCV有一定的帮助,需要的可以参考一下
    2021-12-12
  • SpringBoot+Swagger-ui自动生成API文档

    SpringBoot+Swagger-ui自动生成API文档

    今天小编就为大家分享一篇关于SpringBoot+Swagger-ui自动生成API文档,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 隐藏idea的.idea和.mvn文件的解决方案

    隐藏idea的.idea和.mvn文件的解决方案

    这篇文章主要介绍了隐藏idea的.idea和.mvn文件的解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • java 方法与数组基础使用详解

    java 方法与数组基础使用详解

    Java语言中的“方法”(Method)在其他语言当中也可能被称为“函数”(Function),数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同。Java 语言中提供的数组是用来存储固定大小的同类型元素
    2022-04-04
  • 关于IDEA MybatisX插件的使用小技巧

    关于IDEA MybatisX插件的使用小技巧

    这篇文章主要介绍了关于MybatisX插件的使用小技巧,MybatisX是IDEA的一款第三方插件,可以极大地提升我们的开发效率,一起来看看吧
    2023-03-03
  • springboot启动后卡住无日志的几种情况小结

    springboot启动后卡住无日志的几种情况小结

    这篇文章主要介绍了springboot启动后卡住无日志的几种情况小结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • java8 Stream大数据量List分批处理切割方式

    java8 Stream大数据量List分批处理切割方式

    这篇文章主要介绍了java8 Stream大数据量List分批处理切割方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • springmvc4+hibernate4分页查询功能实现

    springmvc4+hibernate4分页查询功能实现

    本篇文章主要介绍了springmvc4+hibernate4分页查询功能实现,Springmvc+hibernate成为现在很多人用的框架整合,有兴趣的可以了解一下。
    2017-01-01

最新评论