Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >抛砖引玉NIO

抛砖引玉NIO

作者头像
三哥
发布于 2020-01-17 02:53:41
发布于 2020-01-17 02:53:41
4040
举报
文章被收录于专栏:java工会java工会

NIO

◆ ◆ ◆ ◆

在软件系统中,由于I/O的速度远比内存速度慢,所以I/O很容易成为系统的瓶颈。New I/O的简称,与旧式基于流的I/O相对。拥有如下特性:

  1. 为所有的原始类型提供Buffer缓存支持
  2. 使用Java.nio.charset.Charset作为字符集编码解码解决方案
  3. 增加通道Channel对象,作为新的原始I/O抽象
  4. 支持锁和内存映射文件的文件访问接口
  5. 提供了基于Selector的异步网络I/O
  6. 以(Block)块为基本单位处理数据

最为重要的两个组件是缓冲Buffer和通道Channel。缓冲是一块连续的内存,是NIO读写数据的中转地。通道表示缓冲数据的源头或者目的地,用于向缓冲读取或者写入数据,是访问缓冲的接口,关系如图

Channel是一个双向通道,既可读,又可写。类似于Stream,但是Stream是单向的。应用程序不能直接对Channel进行读写操作,必须通过Buffer。比如在读一个Channel的时候,需要将数据读到相应的Buffer,然后从Buffer中读取。比如在读文件时,首先将文件打开,取得文件的Channel

下面用一个文件复制的例子展示读取文件和写入文件的操作

Buffer的基本原理

◆ ◆ ◆ ◆

Buffer有三个重要参数,分别如下

写模式:

  1. position位置:当前缓冲区的位置,将从position的下一个位置写数据
  2. capactiy容量:缓冲区的总容量上限
  3. limit上限:缓冲区的实际上限,他总是小于或者等于容量。

读模式:

  1. position位置:当前缓冲区读取的位置,将从此位置后,读取数据
  2. capactiy容量:缓冲区的总容量上限
  3. limit上限:代表可读取的总容量,和上写写入的数据量相等

举个Buffer的例子

首先分配15个字节的缓冲,p=0,c=15,l=15,如下图

接着Buffer中被放入了10个byte,因此p向前移动,因为p位置始终指向下一个即将输入的位置,所以p=10,c和l不变,如下图

接着执行flip()操作。该操作会重置p。通常,将Buffer从写模式转换为读模式时需要执行此方法。flip()操作不仅重置了当前的p=0,还将limit设置到p的位置,这样做是防止在读模式中,读到应用程序根本没有操作的区域,此时如下图

接着执行5次读操作,和写操作一样,读操作也会设置p到当前位置,如下图

最后执行flip(),p归零,limit设置到position的位置,如下图

Buffer的相关操作

◆ ◆ ◆ ◆

1.Buffer的创建:有两种方式:

(1)使用静态方法allocate()从堆中分配缓冲区

(2)从一个既有数组中创建缓冲区

2.重置和清空缓冲区

(1)rewind():将position置零,并清楚标志位mark,他的作用在于提取Buffer的有效数据做准备

(2)clear():将position置零,同时将limit设置为capacity的大小,并清除了标志mask。由于清除了limit,就无法得知Buffer内哪些数据是真实有效的,该方法用于为重新写Buffer做准备

(3)flip():先将limit设置到position的位置,然后将position置零,并清除标志位mark,用在读写转换时使用

3.读/写缓冲区:比如get(),put()等方法

4.标志缓冲区:标志mark缓冲区是一项在数据处理时很有用的功能,他就像书签一样,在数据处理过程中,可以随时记录当前位置。在任意时刻,回到这个位置,从而加快和简化数据处理流程。主要方法为:

mark():记录当前位置

reset():恢复到mark所在的位置

5.复制缓冲区:以原缓冲区为基础,生成一个完全一样的新缓冲区,用duplicate()。这个函数对处理复杂的Buffer数据很好用,因为新生成的缓冲区和原缓冲共享相同的内存数据,并且一方的数据改动都相互可见,但两者又独立维护了各自的position,limit,mark,增加了灵活性。

6.缓冲分片:slice();将现有缓冲区中,创建新的子缓冲区,子缓冲区和父缓冲区共享数据。这个方法有助于将系统模块化。当需要处理一个Buffer的一个片段时,可以使用slice()方法获得一个子缓冲区,将后就像处理普通缓冲区一样处理,无需考虑缓冲区的边界问题。

7.只读缓冲区:用asReadOnlyBuffer()方法得到一个当前缓冲区一致的,并且共享内存数据的只读缓冲区。只读缓冲区对于数据安全非常有用。当缓冲区作为参数传递给对象的某个方法时,由于无法确定该方法是否破坏缓冲区的数据,此时,使用只读缓冲区可以保证数据不被修改。同时,因为只读缓冲区和原始缓冲区是共享内存块的,因此对原始缓冲区修改,只读缓冲区可见。

8.文件映射到内存:使用FileChannel.map()

9.处理结构化数据:称为散射(Scattering)和聚集(Gathering)。散射是指将数据读入一组Buffer中,而不仅仅是一个。聚集相反,是指将数据写入一组Buffer中。主要通过ScatteringByteChannel和GatheringByteChannel接口提供操作。

- end -

祝各位人人都能涨20K!

每个人都是技术大牛!

点击关注,不要走开哟~

- TEN END -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java工会 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
NIO之Buffer解读
Java NIO 中的 Buffer 用于和 NIO 通道进行交互。数据是从通道读入缓冲区,从缓冲 区写入到通道中的。
一个风轻云淡
2023/10/15
2090
NIO之Buffer解读
NIO之Buffer缓冲区
Buffer缓冲区,所谓的缓冲区其实就是在内存中开辟的一段连续空间,用来临时存放数据。
云飞扬
2022/04/25
3170
Java NIO-3.Buffer
Java NIO Buffers用来和NIO Channels交互。正如前文所述,数据从通道中读到缓冲区,或者从缓冲区写到通道。 缓冲区本质上是一块能写入数据,并延迟读取的内存。这块内存被包装成一个NIO Buffer类,并提供了一组方法简化对它的访问。
悠扬前奏
2019/05/30
4270
Java Nio 基本概念&操作
Java Nio 基本概念,相关组件介绍和一些基本操作
俺也想起舞
2020/10/30
5000
Java Nio 基本概念&操作
NIO基础知识点整理---selector除外
是JVM在I/O方面的效率不足,导致程序效率降低。在操作系统中,可以从硬件上直接读取大块的数据,而JVM的I/O更喜欢小块的数据读取,相当于操作系统视同大卡车运来很多数据,JVM的I/O就喜欢一铲子一铲子的加工这些数据。
大忽悠爱学习
2021/12/10
3910
NIO基础知识点整理---selector除外
Java网络编程——NIO三大组件Buffer、Channel、Selector
Java NIO(Java Non-Blocking IO)也就是非阻塞IO,说是非阻塞IO,其实NIO也支持阻塞IO模型(默认就是),相对于BIO来说,NIO最大的特点是支持IO多路复用模式,可以通过一个线程监控多个IO流(Socket)的状态,来同时管理多个客户端,极大提高了服务器的吞吐能力。
DannyHoo
2022/08/04
3660
Java网络编程——NIO三大组件Buffer、Channel、Selector
NIO详解
NIO (New lO)也有人称之为java non-blocking lO是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java lO API。
冬天vs不冷
2025/01/21
1700
NIO详解
Java的NIO之ByteBuffer底层分析
类ByteBuffer是Java nio程序经常会用到的类,也是重要类 ,我们通过源码分析该类的实现原理。
bear_fish
2018/09/19
1.3K0
Java的NIO之ByteBuffer底层分析
Java NIO三件套之Buffer实现原理解析
如上图所示,对于Java中的所有基本类型,都会有一个具体的Buffer类型与之对应,一般我们最经常使用的是ByteBuffer。
玖柒的小窝
2021/12/11
2400
Java NIO三件套之Buffer实现原理解析
【Netty】「NIO」(一)认识 ByteBuffer
本篇博文是《从0到1学习 Netty》中 NIO 系列的第一篇博文,主要内容是介绍 NIO 的核心之一 Buffer 中的 ByteBuffer,往期系列文章请访问博主的 Netty 专栏,博文中的所有代码全部收集在博主的 GitHub 仓库中;
sidiot
2023/08/30
2860
【Netty】「NIO」(一)认识 ByteBuffer
02.Netty与NIO之前世今生
在 NIO 中有几个核心对象需要掌握:缓冲区(Buffer)、选择器(Selector)、通道(Channel)
云扬四海
2022/05/10
2570
02.Netty与NIO之前世今生
NIO~~
NIO 有三大核心部分:Channel( 通道) ,Buffer( 缓冲区), Selector( 选择器)
大忽悠爱学习
2022/05/06
9090
NIO~~
NIO 和 IO 到底有什么区别?别说你不会!
通道是对原 I/O 包中的流的模拟。到任何目的地(或来自任何地方)的所有数据都必须通过一个 Channel 对象(通道)。
Java技术栈
2020/03/17
1.3K0
NIO 和 IO 到底有什么区别?别说你不会!
【Netty】NIO 缓冲区 ( Buffer ) 组件
下图是 NIO 三大核心组件 , 选择器 ( Selector ) , 通道 ( Channel ) , 缓冲区 ( Buffer ) , 与 服务器端线程 , 客户端 , 结构图 ;
韩曙亮
2023/03/27
6310
【Netty】NIO 缓冲区 ( Buffer ) 组件
java nio
文章目录 1. 缓冲区(Buffer) 1.1. 常用的方法 1.2. 核心属性 1.3. 直接缓冲区 1.4. 非直接缓冲区 2. 通道(Channel) 2.1. 获取通道 2.2. 实例 2.3. 通道之间指定进行数据传输 2.4. 分散读取 2.5. 聚集写入 2.6. NIO阻塞式 3. Selector(选择器) 3.1. SelectionKey 3.2. NIO非阻塞式 4. 参考文章 缓冲区(Buffer) 负责数据的存取,实际上就是一个数组,用于存储不同的数据 除了布尔类型之后,其他
爱撒谎的男孩
2019/12/31
1.1K0
浅谈NIO
说到NIO大家都不会陌生,它是JDK中提供的IO工具集。 它又被称作为New I/O或Non Blocking I/O。相较于传统面向流的java.io,nio是完全面向缓冲的I/O,它提供了更底层的操作。
曲水流觞
2019/10/27
6470
浅谈NIO
Java.NIO编程一览笔录
Java标准IO 与 Java NIO 的简单差异示意: Java标准IO Java NIO API调用 简单 复杂 底层实现 面向流(stream),单向 面向通道(channel),释放CPU、内存压力 成效 同步阻塞 同步非阻塞 数据窥视 阻塞读取,要么足够,要么没有 使用缓冲区(Buffer), 读数据时需要检查是否足够 处理数据的线程数 1:1(一个线程处理一个流) 1:N(选择器(Selector),多路复用,可以一个或几个少量线程管理多个通道) Java N
斯武丶风晴
2018/03/01
1.3K0
Java.NIO编程一览笔录
Java NIO、Channel、Selector 详解
Buffer 是一个特定原始类型的容器。Buffer 是一个原始类型的线性的、有限序列,除了 Buffer 存储的内容外,关键属性还包括:capacity, limit 和 position。
Yano_nankai
2019/11/10
1.2K0
Java NIO、Channel、Selector 详解
NIO
详细知识参考我有道云笔记 package com.shi.nio; import java.nio.ByteBuffer; /** * * @author shiye * 一、缓冲区(Buffer):在 Java NIO 中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据 * * 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区: * ByteBuffer * CharBuffer * ShortBuffer * IntBuffer * LongBuf
用户5927264
2019/10/15
7470
Java NIO 之 Channel 和 BufferChannelbufferPositionLimitCapacityJava NIO 读写文件实例程序参考
Java NIO中,channel用于数据的传输。类似于传统IO中的流的概念。channel的两端是buffer和一个entity,不同于IO中的流,channel是双向的,既可以写入,也可以读取。而流则是单向的,所以channel更加灵活。我们在读取数据或者写入数据的时候,都必须经过channel和buffer,也就是说,我们在读取数据的时候,先利用channel将IO设备中的数据读取到buffer,然后从buffer中读取,我们在写入数据的时候,先将数据写入到buffer,然后buffer中的数据再通过channel传到IO设备中。
desperate633
2018/08/22
9330
Java NIO 之 Channel 和 BufferChannelbufferPositionLimitCapacityJava NIO 读写文件实例程序参考
相关推荐
NIO之Buffer解读
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档