mappedbytebuffer_Java NIO Buffer【MappedByteBuffer】概述与FileChannel的联系

 NIO【Non-blocking IO非阻塞式IO】,可以让你非阻塞的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似,主要分为3部分:Channels and Buffers and Selectors(通道和缓冲区和选择器)今天我们要讲的就是Buffer概述

听歌时间

01

Buffer概述

/**
 * Java NIO中的Buffer用于和NIO通道{Channel【FileChannel|SocketChannel】}进行交互,
 * 数据是从通道读入缓冲区,从缓冲区写入到通道中的。
 * 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。
 * 这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。
 * 用于特定基本类型的数据的缓冲区容器,每个非布尔基本类型都有这个类的一个子类
 * ByteBuffer , CharBuffer , DoubleBuffer , FloatBuffer , IntBuffer , LongBuffer , ShortBuffer
 * 其中和ByteBuffer相关的子类有3个:
 * MappedByteBuffer,HeapByteBuffer,DirectByteBuffer extends MappedByteBuffer
 * 是特定原始类型的元素的线性有限序列缓冲区。除了其内容【缓冲区数组】,
 * 缓冲区对象还有其它3个基本属性
 * 1:capacity:它所包含的元素数量叫缓冲区的容量。缓冲区的容量永远不会为负且永远不会改变
 * 2:limit:第一个不能被读/写的元素的索引叫缓冲区的限制。缓冲区的限制永远不大于缓冲区的容量
 * 3:position:下一个要读取或写入的元素的索引叫缓冲区的位置。缓冲区的位置永远不会大于其限制。
 * Buffer类的每个子类定义了一系列get和put操作:
 * 相对的读写操作每次都从当前位置开始读写,并将位置+1
 * 绝对的读写操作采用显式的元素索引,并不影响位置
 * 无论是相对的还是绝对的读写操作,索引都不能超过【exceeds】其限制
 * 标记,位置,极限和容量值满足以下关系:
 * 0 <= mark <= position <= limit <= capacity
 * 标记和重置、清理,翻转和倒带
 * 调用reset方法一定保证mark方法被调用过
 * mark方法源码:
 * mark = position;return this;
 * reset方法源码:
 * int m = mark;if (m < 0){throw new InvalidMarkException()};position = m;return this;
 * clear方法源码:
 * position = 0;limit = capacity;mark = -1;return this;
 * flip方法源码:
 * limit = position;position = 0;mark = -1;return this;
 * rewind方法源码:
 * position = 0;mark = -1;return this;
 * 读与写操作之间要调用flip方法
 * 线程不安全,可以链式调用
 * b.flip().position(23).limit(42);
 *
 */

02

代码演示

import java.nio.ByteBuffer;import java.util.Arrays;public class ByteBufferTest {public static void main(String[] args) {//根据指定的容量创建一个字节缓冲区,两种方式//分配5个字节
        ByteBuffer byteBuffer = ByteBuffer.allocate(5);//ByteBuffer.wrap(new byte[5]);// 往 ByteBuffer放入数值
        byteBuffer.put((byte)10);
        byteBuffer.put((byte)20);//byteBuffer.putInt(1000);//放入一个int占4个字节
        System.out.printf("打印一下字节数组: %s%n",Arrays.toString(byteBuffer.array()));
        System.out.printf("打印一下是否有字节数组: %s%n",byteBuffer.hasArray());
        System.out.printf("打印一下指针位置: %s%n",byteBuffer.position());
        System.out.printf("打印一下字节缓冲区容量: %s%n",byteBuffer.capacity());
        System.out.printf("打印一下字节缓冲区限制: %s%n",byteBuffer.limit());
        System.out.printf("打印一下字节缓冲区从当前位置到限制之间的剩余元素: %s%n",byteBuffer.remaining());
        System.out.printf("从当前位置到限制之间是否有剩余元素: %s%n",byteBuffer.hasRemaining());
        System.out.printf("是否是直接缓冲区: %s%n",byteBuffer.isDirect());
        System.out.printf("该缓冲区是否是只读: %s%n",byteBuffer.isReadOnly());//设置位置和限制
        byteBuffer.flip().position(2).limit(4);
        System.out.printf("打印一下字节数组: %s%n",Arrays.toString(byteBuffer.array()));//get方法获取的是position+1的索引对应的值
        System.out.printf("flip之后获取位置为2的数据: %s%n",byteBuffer.get());
        System.out.printf("标记后重置: %s%n",byteBuffer.mark().reset());
        byteBuffer.put((byte)60);
        System.out.printf("重新获取位置: %s%n",byteBuffer.position());//该方法和flip方法差不多,都用于读写切换,只不过rewind方法前提是limit被合理的设置
        byteBuffer.rewind();
        System.out.printf("重新获取值: %s%n",byteBuffer.get());//重置为最开始创建的时候,只不过没有清除数据
        System.out.printf("重置但不清除数据: %s%n",byteBuffer.clear());//创建一个新的剩余内容子共享缓冲区,【也就是说字节数组是共享的】// 该新的缓冲区是指定缓冲区的剩余部分,修改哪一个另外一个都会同步修改//这两个缓冲区的位置,限制和标记值将是独立的//通过position++加上offset来定位在原数组中的位置
        ByteBuffer subByteBuffer = byteBuffer.slice();
        subByteBuffer.put((byte)30);
        System.out.printf("打印一下子字节数组: %s%n",Arrays.toString(subByteBuffer.array()));//只有调用slice方法,offset才会被设置
        System.out.printf("打印一下缓冲区偏移量: %s%n",subByteBuffer.arrayOffset());
        System.out.printf("打印一下子指针位置: %s%n",subByteBuffer.position());
        System.out.printf("打印一下子字节缓冲区容量: %s%n",subByteBuffer.capacity());
        System.err.printf("打印一下字节数组: %s%n",Arrays.toString(byteBuffer.array()));
        System.err.printf("打印一下指针位置: %s%n",byteBuffer.position());
        System.err.printf("打印一下字节缓冲区容量: %s%n",byteBuffer.capacity());
        System.err.printf("打印一下字节缓冲区限制: %s%n",byteBuffer.limit());
        byteBuffer.rewind();
        System.err.printf("获取: %s%n",byteBuffer.get());
    }
}

03

MappedByteBuffer概述与联系

直接字节缓冲器,其内容是文件的存储器映射区域。
映射的字节缓冲区是通过FileChannel.map方法创建的。此类扩展了具有特定于内存映射文件区域的操作的ByteBuffer类。

映射字节缓冲区及其表示的文件映射在缓冲区本身被垃圾回收之前保持有效。

映射字节缓冲区的内容可以随时更改,例如,如果该程序或其他映射文件的对应区域的内容被更改。
这种变化是否发生,何时发生,是操作系统依赖的,因此是未指定的。

映射字节缓冲区的全部或部分可能在任何时候变得无法访问,例如映射文件被截断。
访问映射字节缓冲区的不可访问区域的尝试不会更改缓冲区的内容,
并将导致在访问时或稍后的时候抛出未指定的异常。因此,强烈建议您采取适当的预防措施,
以避免该程序或同时运行的程序对映射文件进行操作,但读取或写入文件的内容除外。

映射的字节缓冲区的行为与普通的直接字节缓冲区不同。

04

FileChannel

d0ba552a2e9b4f930f19cd6c6d4dc201.png

6d199dfb9fd3058ad48d540ae7a40c1a.gif

写在最后

总结:今天花了点时间写了关于Buffer的概述,关于实战部分请参考往期精彩文章

>>>往期精彩文章

使用一种全新的方式【java NIO】拆分大电影文件,并合并分割后的文
件为电影文件

如果喜欢,欢迎点赞分享给你身边要的人!

我欲寻花问路,直入白云深处。

0cf003728cd5f860d0e6d93790ef7971.gif

156c5dbe55a2cda86af6d19fb78e0a16.gif

62a85eb7500b2a35dfce5cbc3f11fae3.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[初级]Java命令学习系列(六)——jinfo

转载自 [初级]Java命令学习系列&#xff08;六&#xff09;——jinfojinfo可以输出java进程、core文件或远程debug服务器的配置信息。这些配置信息包括JAVA系统参数及命令行参数,如果进程运行在64位虚拟机上&#xff0c;需要指明-J-d64参数&#xff0c;如&#xff1a;jinfo -J-…

idea 调整代码格式

1. 格式化代码时&#xff0c; 不想格式化注释&#xff0c; refer2 IDEA格式化代码时&#xff0c;不想格式化注释怎么办&#xff1f;_缘自天方的博客-CSDN博客_idea不格式化注释很简单&#xff0c;只需要把 Enable JavaDoc formatting 去掉选中状态即可。附图如下&#xff1a;h…

python递归算法_python递归算法(上)

什么是递归 在函数内部&#xff0c;是可以调用其他函数的。如果一个函数在内部调用自身&#xff0c;就称这个函数就是递归函数。举个例子&#xff1a; 实现一个可以自定义重复打印你好的函数。 要实现重复打印&#xff0c;可能我们立马就会想到使用循环。如果要求不能使用循环呢…

[初级]Java命令学习系列(七)——javap

转载自 [初级]Java命令学习系列&#xff08;七&#xff09;——javapjavap是jdk自带的一个工具&#xff0c;可以对代码反编译&#xff0c;也可以查看java编译器生成的字节码。一般情况下&#xff0c;很少有人使用javap对class文件进行反编译&#xff0c;因为有很多成熟的反编译…

局域网物理机怎么访问虚拟机

前言 友链: 原文地址 ❓-背景- 现有物理机A&#xff0c;B。A中安装了虚拟机VM上面部署了服务&#xff08;这里以mysql为例&#xff09;。B需要访问A虚拟机中部署的服务。 -环境- 物理机A&#xff08;192.168.135.161&#xff09;物理机B&#xff08;192.168.135.162&#xf…

springmvc新建拦截器

【1】web.xml中配置springmvc的配置文件路径 <!-- 配置 DispatcherServlet --><servlet><servlet-name>springDispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!…

householder变换qr分解matlab_【基础教程】Matlab实现傅里叶变换

傅立叶变换傅立叶变换是一种常见的分析方法&#xff0c;傅立叶变换将满足一定条件的函数表示为一些函数的加权和(或者积分)。可以分为四个类别&#xff1a; 1. 非周期连续性信号 对应于傅里叶变换&#xff0c;频域连续非周期 2. 周期性连续性信号 对应于傅立叶级数&#xff0c;…

Java开发必会的Linux命令

转载自 Java开发必会的Linux命令 必会Linux命令清单查找文件 find / -name filename.txt 根据名称查找/目录下的filename.txt文件。 find . -name "*.xml" 递归查找所有的xml文件 find . -name "*" |xargs grep "hello" 递归查找所有文件内容中包…

http连接池

转自 &#xff1a; 最近学习了Http连接池 - 五月的仓颉 - 博客园 【1】使用线程池与否的程序性能 我的任务定义&#xff1a;从0 累加到 100w&#xff1b; public class ThreadPoolMain {/*** 线程池测试*/private static final AtomicInteger THREAD_EXECUTED_TOTAL new At…

Quartz定时任务的基本搭建

前言 个人地址&#xff1a;Quartz定时任务的基本搭建 Quartz是一个完全由Java编写的开源作业调度框架&#xff0c;为在java应用程序中进行作业调度提供了简单又强大的机制。 Quartz中分为几个核心概念&#xff1a; Job - 表示一个工作&#xff08;任务&#xff09;&#xff0…

matlab 定义一个有自变量的方程_常微分方程:(第四章) 高阶微分方程

参考《常微分方程》第三版&#xff08;王高雄&#xff09;常微分方程王高雄 第四章 高阶微分方程_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com对于高阶微分方程&#xff0c;线性部分见4、5章&#xff0c;非线性部分见6章。4.1 线性微分方程的一般理论定义&#xff…

HttpClient api-连接池

【README】 本文 refer2 HttpClient Tutorialhttps://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/pdf/httpclient-tutorial.pdf 【2.3】http连接管理器 【2.3.1】可管理的连接与连接管理器 1&#xff09;http连接简述 HTTP 连接是复杂的、有状态的、线程…

使用SpringBoot搭建一个简单的webSocket服务

前言 个人地址&#xff1a;使用SpringBoot搭建一个简单的webSocket服务 什么是WebSocket&#xff1f; WebSocket是一个HTML5新增的协议,它的目的在浏览器和服务器之间建立一个不受限的双向实时通信的通道。比如&#xff0c;服务器可以任意时刻发送消息给浏览器。它是基于TCP&am…

cas 登录之后不跳转_图解JWT如何用于单点登录

点击上方“Java知音”&#xff0c;选择“置顶公众号”技术文章第一时间送达&#xff01;作者&#xff1a;流云诸葛http://cnblogs.com/lyzg/p/6132801.html推荐阅读(点击即可跳转阅读)1. 淘宝服务端高并发分布式架构演进之路2. IntelliJ IDEA 从入门到上瘾教程&#xff0c;2019…

转:java网络编程-HTTP编程

转自&#xff1a; java网络编程-HTTP编程_Stillsings的博客-CSDN博客HTTP编程Java HTTP编程支持模拟成浏览器的方式去访问网页URL, Uniform Resource Locator&#xff0c;代表一个资源URLConnection获取资源连接器根据URL的openConnection&#xff08;&#xff09;方法获得URL…

Centos7-通过RPM方式安装MySQL5.7

前言 Hallo&#xff0c;我们都知道开发时数据库是不可或缺的&#xff0c;本文就简单记录一下安装MySQL数据库的其中一种方式吧。 系统环境 系统&#xff1a;CentOS Linux 7.5 数据库版本&#xff1a;5.7 安装步骤 1. 从官网获取安装包 官方下载地址&#xff1a;https://ww…

python开发工具下所有软件都打不开_Python 开发工具链全解

可能刚开始学习Python时&#xff0c;有人跟你说可以将源文件所在的文件夹添加到 PYTHONPATH环境变量中&#xff0c;然后可以从其他位置导入此代码。在大多数情况下&#xff0c;这个人常常忘记补充这是一个非常糟糕的主意。有些人在互联网上发现了这一点&#xff0c;其他人却要看…

利用F#库canopy进行UI测试

虽然Selenium是一个流行的UI测试库&#xff0c;但基于它创建的测试却有着脆弱与不可靠等常见的问题。InfoQ与canopy的作者Chris Holt进行了一次访谈&#xff0c;以便更深入地了解canopy这个在Selenium的基础上所创建的F#库。 InfoQ&#xff1a;你能否为我们介绍一下canopy&…

转: Springboot — 用更优雅的方式发HTTP请求(RestTemplate详解)

转自&#xff1a; Springboot — 用更优雅的方式发HTTP请求(RestTemplate详解) - Java知音号 - 博客园RestTemplate是Spring提供的用于访问Rest服务的客户端&#xff0c;RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。 我之前的HTTP开发是…

SpringBoot整合Shiro权限框架

前言 在系统管理中&#xff0c;权限是非常重要的一个环节。目前权限框架中使用比较多的有Shiro、Spring Security。&#x1f383; 本篇简单写一下SpringBoot整合Shiro权限框架小栗子&#x1f330;。 个人博客地址&#xff1a;SpringBoot整合Shiro权限框架 介绍Shiro Apache S…